Coverage Report

Created: 2026-05-30 06:49

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/S2OPC/src/Common/crypto/sopc_pki_stack.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 <stddef.h>
21
#include <string.h>
22
23
#include "sopc_assert.h"
24
#include "sopc_buffer.h"
25
#include "sopc_common_constants.h"
26
#include "sopc_crypto_profiles.h"
27
#include "sopc_filesystem.h"
28
#include "sopc_helper_string.h"
29
#include "sopc_key_manager_lib_itf.h"
30
#include "sopc_logger.h"
31
#include "sopc_macros.h"
32
#include "sopc_mem_alloc.h"
33
#include "sopc_pki_stack.h"
34
#include "sopc_pki_stack_lib_internal_itf.h"
35
#include "sopc_pki_struct_lib_internal.h"
36
37
#ifndef STR_TRUSTLIST_NAME
38
0
#define STR_TRUSTLIST_NAME "/updatedTrustList"
39
#endif
40
41
0
#define STR_TRUSTED "/trusted"
42
0
#define STR_TRUSTED_CERTS "/trusted/certs"
43
0
#define STR_TRUSTED_CRL "/trusted/crl"
44
0
#define STR_ISSUERS "/issuers"
45
0
#define STR_ISSUERS_CERTS "/issuers/certs"
46
0
#define STR_ISSUERS_CRL "/issuers/crl"
47
0
#define STR_REJECTED "/rejected"
48
49
0
#define HEX_THUMBPRINT_SIZE 40
50
51
#ifndef WITH_NO_CRYPTO
52
53
static const SOPC_PKI_LeafProfile g_leaf_profile_rsa_sha256_2048_4096 = {.mdSign = SOPC_PKI_MD_SHA256,
54
                                                                         .pkAlgo = SOPC_PKI_PK_RSA,
55
                                                                         .RSAMinimumKeySize = 2048,
56
                                                                         .RSAMaximumKeySize = 4096,
57
                                                                         .bApplySecurityPolicy = true,
58
                                                                         .keyUsage = SOPC_PKI_KU_NONE,
59
                                                                         .extendedKeyUsage = SOPC_PKI_EKU_NONE,
60
                                                                         .sanApplicationUri = NULL,
61
                                                                         .sanURL = NULL};
62
63
static const SOPC_PKI_ChainProfile g_chain_profile_rsa_sha256_2048 = {.curves = SOPC_PKI_CURVES_ANY,
64
                                                                      .mdSign = SOPC_PKI_MD_SHA256_OR_ABOVE,
65
                                                                      .pkAlgo = SOPC_PKI_PK_RSA,
66
                                                                      .RSAMinimumKeySize = 2048,
67
                                                                      .bDisableRevocationCheck = false};
68
69
static const SOPC_PKI_LeafProfile g_leaf_profile_rsa_sha1_1024_2048 = {.mdSign = SOPC_PKI_MD_SHA1_AND_SHA256,
70
                                                                       .pkAlgo = SOPC_PKI_PK_RSA,
71
                                                                       .RSAMinimumKeySize = 1024,
72
                                                                       .RSAMaximumKeySize = 2048,
73
                                                                       .bApplySecurityPolicy = true,
74
                                                                       .keyUsage = SOPC_PKI_KU_NONE,
75
                                                                       .extendedKeyUsage = SOPC_PKI_EKU_NONE,
76
                                                                       .sanApplicationUri = NULL,
77
                                                                       .sanURL = NULL};
78
79
static const SOPC_PKI_ChainProfile g_chain_profile_rsa_sha1_1024 = {.curves = SOPC_PKI_CURVES_ANY,
80
                                                                    .mdSign = SOPC_PKI_MD_SHA1_OR_ABOVE,
81
                                                                    .pkAlgo = SOPC_PKI_PK_RSA,
82
                                                                    .RSAMinimumKeySize = 1024,
83
                                                                    .bDisableRevocationCheck = false};
84
85
typedef struct Profile_Cfg
86
{
87
    const SOPC_PKI_ChainProfile* chain;
88
    const SOPC_PKI_LeafProfile* leaf;
89
    const SOPC_SecurityPolicy_ID id;
90
} Profile_Cfg;
91
92
static const Profile_Cfg g_all_profiles[] = {
93
    {.id = SOPC_SecurityPolicy_Aes256Sha256RsaPss_ID,
94
     .leaf = &g_leaf_profile_rsa_sha256_2048_4096,
95
     .chain = &g_chain_profile_rsa_sha256_2048},
96
    {.id = SOPC_SecurityPolicy_Aes128Sha256RsaOaep_ID,
97
     .leaf = &g_leaf_profile_rsa_sha256_2048_4096,
98
     .chain = &g_chain_profile_rsa_sha256_2048},
99
    {.id = SOPC_SecurityPolicy_Basic256Sha256_ID,
100
     .leaf = &g_leaf_profile_rsa_sha256_2048_4096,
101
     .chain = &g_chain_profile_rsa_sha256_2048},
102
    {.id = SOPC_SecurityPolicy_Basic256_ID,
103
     .leaf = &g_leaf_profile_rsa_sha1_1024_2048,
104
     .chain = &g_chain_profile_rsa_sha1_1024},
105
};
106
107
static const SOPC_PKI_KeyUsage_Mask g_appKU = SOPC_PKI_KU_KEY_ENCIPHERMENT | SOPC_PKI_KU_KEY_DATA_ENCIPHERMENT |
108
                                              SOPC_PKI_KU_DIGITAL_SIGNATURE | SOPC_PKI_KU_NON_REPUDIATION;
109
static const SOPC_PKI_KeyUsage_Mask g_usrKU =
110
    SOPC_PKI_KU_DIGITAL_SIGNATURE; // it is not part of the OPC UA but it makes sense to keep it
111
static const SOPC_PKI_ExtendedKeyUsage_Mask g_clientEKU = SOPC_PKI_EKU_SERVER_AUTH;
112
static const SOPC_PKI_ExtendedKeyUsage_Mask g_serverEKU = SOPC_PKI_EKU_CLIENT_AUTH;
113
static const SOPC_PKI_ExtendedKeyUsage_Mask g_userEKU = SOPC_PKI_EKU_NONE;
114
115
/**
116
 * Static functions declaration
117
 */
118
119
static void sopc_pki_clear(SOPC_PKIProvider* pPKI);
120
121
// Copy newPKI content into currentPKI by preserving currentPKI mutex and then clear previous PKI content.
122
// Then frees the new PKI structure.
123
static void sopc_internal_replace_pki_and_clear(SOPC_PKIProvider* currentPKI, SOPC_PKIProvider** newPKI);
124
125
static SOPC_ReturnStatus sopc_pki_check_application_uri(const SOPC_CertificateList* pToValidate,
126
                                                        const char* applicationUri);
127
128
static SOPC_ReturnStatus sopc_pki_check_security_level_of_the_update(const SOPC_CertificateList* pTrustedCerts,
129
                                                                     const SOPC_CRLList* pTrustedCrl,
130
                                                                     const SOPC_CertificateList* pIssuerCerts,
131
                                                                     const SOPC_CRLList* pIssuerCrl,
132
                                                                     const char* securityPolicyUri);
133
134
static SOPC_ReturnStatus sopc_pki_merge_certificates(SOPC_CertificateList* pLeft,
135
                                                     SOPC_CertificateList* pRight,
136
                                                     SOPC_CertificateList** ppRes);
137
138
static SOPC_ReturnStatus write_cert_to_der_files(SOPC_CertificateList* pRoots,
139
                                                 SOPC_CertificateList* pCerts,
140
                                                 const char* directoryPath,
141
                                                 const bool bEraseExistingFiles);
142
143
static SOPC_ReturnStatus write_crl_to_der_files(SOPC_CRLList* pCrl,
144
                                                const char* directoryPath,
145
                                                const bool bEraseExistingFiles);
146
147
static SOPC_ReturnStatus may_create_pki_folder(const char* pBasePath, const char* pSubPath, char** ppPath);
148
149
static bool ignore_filtered_file(const char* pFilePath);
150
151
static SOPC_ReturnStatus load_certificate_or_crl_list(const char* basePath,
152
                                                      SOPC_CertificateList** ppCerts,
153
                                                      SOPC_CRLList** ppCrl,
154
                                                      bool bIscrl,
155
                                                      bool bDefaultBuild);
156
157
static SOPC_ReturnStatus sopc_pki_load_certificate_and_crl_list_from_store(const char* basePath,
158
                                                                           SOPC_CertificateList** ppTrustedCerts,
159
                                                                           SOPC_CRLList** ppTrustedCrl,
160
                                                                           SOPC_CertificateList** ppIssuerCerts,
161
                                                                           SOPC_CRLList** ppIssuerCrl,
162
                                                                           bool bDefaultBuild);
163
164
static bool pki_updated_trust_list_dir_exists(const char* path);
165
166
static SOPC_ReturnStatus pki_create_from_store(
167
    const char* directoryStorePath,
168
    bool bDefaultBuild, /* If true load the root PKI directory without trust list update,
169
                           if false try to load the updated trust list subdirectory.*/
170
    SOPC_PKIProvider** ppPKI);
171
172
static SOPC_ReturnStatus sopc_pki_merge_crls(SOPC_CRLList* pLeft, SOPC_CRLList* pRight, SOPC_CRLList** ppRes);
173
174
static SOPC_ReturnStatus sopc_pki_remove_cert_by_thumbprint(SOPC_CertificateList** ppList,
175
                                                            SOPC_CRLList** ppCRLList,
176
                                                            const char* pThumbprint,
177
                                                            const char* listName,
178
                                                            bool* pbIsRemoved,
179
                                                            bool* pbIsIssuer);
180
181
static SOPC_ReturnStatus sopc_pki_check_lists(SOPC_CertificateList* pTrustedCerts,
182
                                              SOPC_CertificateList* pIssuerCerts,
183
                                              SOPC_CRLList* pTrustedCrl,
184
                                              SOPC_CRLList* pIssuerCrl,
185
                                              bool* bTrustedCaFound,
186
                                              bool* bIssuerCaFound);
187
188
static SOPC_ReturnStatus sopc_pki_validate_anything(SOPC_PKIProvider* pPKI,
189
                                                    const SOPC_CertificateList* pToValidate,
190
                                                    const SOPC_PKI_Profile* pProfile,
191
                                                    uint32_t* error,
192
                                                    SOPC_PKI_Cert_Failure_Context* context);
193
194
static SOPC_ReturnStatus sopc_pki_check_list_length(SOPC_PKIProvider* pPKI,
195
                                                    SOPC_CertificateList* pTrustedCerts,
196
                                                    SOPC_CRLList* pTrustedCrl,
197
                                                    SOPC_CertificateList* pIssuerCerts,
198
                                                    SOPC_CRLList* pIssuerCrl,
199
                                                    const bool bIncludeExistingList);
200
201
static SOPC_ReturnStatus sopc_pki_get_list_length(const SOPC_CertificateList* pTrustedCerts,
202
                                                  const SOPC_CRLList* pTrustedCrl,
203
                                                  const SOPC_CertificateList* pIssuerCerts,
204
                                                  const SOPC_CRLList* pIssuerCrl,
205
                                                  uint32_t* listLength);
206
207
static const SOPC_PKI_ChainProfile* sopc_pki_get_chain_profile_from_security_policy(const char* uri);
208
209
static const SOPC_PKI_LeafProfile* sopc_pki_get_leaf_profile_from_security_policy(const char* uri);
210
211
/**
212
 * Static functions definition
213
 */
214
215
static void sopc_pki_clear(SOPC_PKIProvider* pPKI)
216
0
{
217
0
    if (NULL == pPKI)
218
0
    {
219
0
        return;
220
0
    }
221
0
    SOPC_ReturnStatus mutStatus = SOPC_Mutex_Lock(&pPKI->mutex);
222
0
    SOPC_ASSERT(SOPC_STATUS_OK == mutStatus);
223
224
0
    SOPC_KeyManager_Certificate_Free(pPKI->pTrustedRoots);
225
0
    SOPC_KeyManager_Certificate_Free(pPKI->pIssuerRoots);
226
0
    SOPC_KeyManager_Certificate_Free(pPKI->pAllRoots);
227
0
    SOPC_KeyManager_Certificate_Free(pPKI->pAllTrusted);
228
0
    SOPC_KeyManager_Certificate_Free(pPKI->pTrustedCerts);
229
0
    SOPC_KeyManager_Certificate_Free(pPKI->pIssuerCerts);
230
0
    SOPC_KeyManager_Certificate_Free(pPKI->pAllCerts);
231
0
    SOPC_KeyManager_CRL_Free(pPKI->pTrustedCrl);
232
0
    SOPC_KeyManager_CRL_Free(pPKI->pIssuerCrl);
233
0
    SOPC_KeyManager_CRL_Free(pPKI->pAllCrl);
234
0
    SOPC_KeyManager_Certificate_Free(pPKI->pRejectedList);
235
0
    SOPC_Free(pPKI->directoryStorePath);
236
0
    mutStatus = SOPC_Mutex_Unlock(&pPKI->mutex);
237
0
    SOPC_ASSERT(SOPC_STATUS_OK == mutStatus);
238
0
    mutStatus = SOPC_Mutex_Clear(&pPKI->mutex);
239
0
    SOPC_ASSERT(SOPC_STATUS_OK == mutStatus);
240
0
}
241
242
// Copy newPKI content into currentPKI by preserving currentPKI mutex and then clear previous PKI content.
243
// Then frees the new PKI structure.
244
static void sopc_internal_replace_pki_and_clear(SOPC_PKIProvider* currentPKI, SOPC_PKIProvider** newPKI)
245
0
{
246
    // tmpPKI used for clear
247
0
    SOPC_PKIProvider tmpPKI = *currentPKI;
248
0
    tmpPKI.mutex = (*newPKI)->mutex;
249
    // Replace all except mutex which shall remain the same since PKI is already in use
250
0
    currentPKI = memcpy(((char*) currentPKI) + sizeof(SOPC_Mutex), ((char*) (*newPKI)) + sizeof(SOPC_Mutex),
251
0
                        sizeof(SOPC_PKIProvider) - sizeof(SOPC_Mutex));
252
    // clear previous PKI data and unused new PKI mutex
253
0
    sopc_pki_clear(&tmpPKI);
254
    // frees unused new PKI structure
255
0
    SOPC_Free(*newPKI);
256
0
    *newPKI = NULL;
257
0
}
258
259
static SOPC_ReturnStatus sopc_pki_check_application_uri(const SOPC_CertificateList* pToValidate,
260
                                                        const char* applicationUri)
261
0
{
262
0
    SOPC_ASSERT(NULL != pToValidate);
263
0
    SOPC_ASSERT(NULL != applicationUri);
264
265
0
    bool ok = SOPC_KeyManager_Certificate_CheckApplicationUri(pToValidate, applicationUri);
266
0
    if (!ok)
267
0
    {
268
0
        char* pThumbprint = SOPC_KeyManager_Certificate_GetCstring_SHA1(pToValidate);
269
0
        const char* thumbprint = NULL == pThumbprint ? "NULL" : pThumbprint;
270
0
        SOPC_Logger_TraceError(SOPC_LOG_MODULE_COMMON,
271
0
                               "> PKI validation failed : the application URI %s is not stored in the URI SAN "
272
0
                               "extension of certificate thumbprint %s",
273
0
                               applicationUri, thumbprint);
274
0
        SOPC_Free(pThumbprint);
275
0
        return SOPC_STATUS_NOK;
276
0
    }
277
0
    return SOPC_STATUS_OK;
278
0
}
279
280
static SOPC_ReturnStatus sopc_pki_check_security_level_of_the_update(const SOPC_CertificateList* pTrustedCerts,
281
                                                                     const SOPC_CRLList* pTrustedCrl,
282
                                                                     const SOPC_CertificateList* pIssuerCerts,
283
                                                                     const SOPC_CRLList* pIssuerCrl,
284
                                                                     const char* securityPolicyUri)
285
0
{
286
    /*
287
    TODO :
288
289
    -1 Add a way to configure the security level for each security policy uri (give them a weight)
290
    -2 For each certificate, retrieve their security policies from their properties.
291
       How to do it? The following issue has been SUBMITTED : https://mantis.opcfoundation.org/view.php?id=8976
292
    */
293
294
0
    SOPC_UNUSED_ARG(pTrustedCerts);
295
0
    SOPC_UNUSED_ARG(pTrustedCrl);
296
0
    SOPC_UNUSED_ARG(pIssuerCerts);
297
0
    SOPC_UNUSED_ARG(pIssuerCrl);
298
0
    SOPC_UNUSED_ARG(securityPolicyUri);
299
300
0
    return SOPC_STATUS_OK;
301
0
}
302
303
static SOPC_ReturnStatus sopc_pki_merge_certificates(SOPC_CertificateList* pLeft,
304
                                                     SOPC_CertificateList* pRight,
305
                                                     SOPC_CertificateList** ppRes)
306
0
{
307
0
    SOPC_ReturnStatus status = SOPC_STATUS_OK;
308
0
    if (NULL == ppRes)
309
0
    {
310
0
        return SOPC_STATUS_INVALID_PARAMETERS;
311
0
    }
312
0
    SOPC_CertificateList* pRes = *ppRes;
313
    /* Left part */
314
0
    if (NULL != pLeft)
315
0
    {
316
0
        status = SOPC_KeyManager_Certificate_Copy(pLeft, &pRes);
317
0
    }
318
    /* Right part */
319
0
    if (NULL != pRight && SOPC_STATUS_OK == status)
320
0
    {
321
0
        status = SOPC_KeyManager_Certificate_Copy(pRight, &pRes);
322
0
    }
323
    /* clear if error */
324
0
    if (SOPC_STATUS_OK != status)
325
0
    {
326
0
        SOPC_KeyManager_Certificate_Free(pRes);
327
0
        pRes = NULL;
328
0
    }
329
0
    *ppRes = pRes;
330
0
    return status;
331
0
}
332
333
#if SOPC_HAS_FILESYSTEM
334
static SOPC_ReturnStatus remove_files(const char* directoryPath)
335
0
{
336
0
    SOPC_ASSERT(NULL != directoryPath);
337
338
0
    SOPC_ReturnStatus status = SOPC_STATUS_OK;
339
0
    SOPC_Array* pFilePaths = NULL;
340
0
    char* pFilePath = NULL;
341
0
    int res = -1;
342
    /* Get the array of file paths from the given directory */
343
0
    SOPC_FileSystem_GetDirResult dirRes = SOPC_FileSystem_GetDirFilePaths(directoryPath, &pFilePaths);
344
0
    if (SOPC_FileSystem_GetDir_OK != dirRes)
345
0
    {
346
0
        SOPC_Logger_TraceError(SOPC_LOG_MODULE_COMMON, "> PKI write to store: failed to open directory <%s>.",
347
0
                               directoryPath);
348
0
        return SOPC_STATUS_NOK;
349
0
    }
350
0
    size_t nbFiles = SOPC_Array_Size(pFilePaths);
351
0
    for (size_t idx = 0; idx < nbFiles && SOPC_STATUS_OK == status; idx++)
352
0
    {
353
0
        pFilePath = SOPC_Array_Get(pFilePaths, char*, idx);
354
0
        res = remove(pFilePath);
355
0
        if (0 != res)
356
0
        {
357
0
            status = SOPC_STATUS_NOK;
358
0
        }
359
0
    }
360
0
    SOPC_Array_Delete(pFilePaths);
361
0
    return status;
362
0
}
363
#else
364
SOPC_ReturnStatus remove_files(const char* directoryPath)
365
{
366
    SOPC_UNUSED_ARG(directoryPath);
367
    return SOPC_STATUS_NOT_SUPPORTED;
368
}
369
#endif /* SOPC_HAS_FILESYSTEM */
370
371
static SOPC_ReturnStatus write_cert_to_der_files(SOPC_CertificateList* pRoots,
372
                                                 SOPC_CertificateList* pCerts,
373
                                                 const char* directoryPath,
374
                                                 const bool bEraseExistingFiles)
375
0
{
376
0
    SOPC_ASSERT(NULL != directoryPath);
377
0
    SOPC_ReturnStatus status = SOPC_STATUS_OK;
378
0
    if (bEraseExistingFiles)
379
0
    {
380
0
        status = remove_files(directoryPath);
381
0
    }
382
0
    if (SOPC_STATUS_OK == status && NULL != pRoots)
383
0
    {
384
0
        status = SOPC_KeyManager_Certificate_ToDER_Files(pRoots, directoryPath);
385
0
    }
386
0
    if (SOPC_STATUS_OK == status && NULL != pCerts)
387
0
    {
388
0
        status = SOPC_KeyManager_Certificate_ToDER_Files(pCerts, directoryPath);
389
0
    }
390
0
    return status;
391
0
}
392
393
static SOPC_ReturnStatus write_crl_to_der_files(SOPC_CRLList* pCrl,
394
                                                const char* directoryPath,
395
                                                const bool bEraseExistingFiles)
396
0
{
397
0
    SOPC_ASSERT(NULL != directoryPath);
398
0
    SOPC_ReturnStatus status = SOPC_STATUS_OK;
399
0
    if (bEraseExistingFiles)
400
0
    {
401
0
        status = remove_files(directoryPath);
402
0
    }
403
0
    if (SOPC_STATUS_OK == status && NULL != pCrl)
404
0
    {
405
0
        status = SOPC_KeyManager_CRL_ToDER_Files(pCrl, directoryPath);
406
0
    }
407
0
    return status;
408
0
}
409
410
static SOPC_ReturnStatus may_create_pki_folder(const char* pBasePath, const char* pSubPath, char** ppPath)
411
0
{
412
0
    SOPC_FileSystem_CreationResult mkdir_res = SOPC_FileSystem_Creation_Error_UnknownIssue;
413
0
    char* pPath = NULL;
414
0
    SOPC_ReturnStatus status = SOPC_StrConcat(pBasePath, pSubPath, &pPath);
415
0
    if (SOPC_STATUS_OK == status)
416
0
    {
417
0
        mkdir_res = SOPC_FileSystem_mkdir(pPath);
418
0
        if (SOPC_FileSystem_Creation_Error_PathAlreadyExists != mkdir_res && SOPC_FileSystem_Creation_OK != mkdir_res)
419
0
        {
420
0
            status = SOPC_STATUS_NOK;
421
0
        }
422
0
    }
423
0
    if (SOPC_STATUS_OK != status)
424
0
    {
425
0
        SOPC_Free(pPath);
426
0
        pPath = NULL;
427
0
    }
428
0
    *ppPath = pPath;
429
0
    return status;
430
0
}
431
432
static bool ignore_filtered_file(const char* pFilePath)
433
0
{
434
0
    char* lastSep = strrchr(pFilePath, '/');
435
0
    if (NULL != lastSep && '.' == lastSep[1])
436
0
    {
437
        // Ignore file if first file character is a dot '.'
438
0
        return true;
439
0
    }
440
0
    return false;
441
0
}
442
443
static SOPC_ReturnStatus load_certificate_or_crl_list(const char* basePath,
444
                                                      SOPC_CertificateList** ppCerts,
445
                                                      SOPC_CRLList** ppCrl,
446
                                                      bool bIscrl,
447
                                                      bool bDefaultBuild)
448
0
{
449
0
    SOPC_ASSERT(NULL != basePath);
450
0
    if (bIscrl)
451
0
    {
452
0
        SOPC_ASSERT(NULL != ppCrl && NULL == ppCerts);
453
0
    }
454
0
    else
455
0
    {
456
0
        SOPC_ASSERT(NULL == ppCrl && NULL != ppCerts);
457
0
    }
458
0
    SOPC_ReturnStatus status = SOPC_STATUS_OK;
459
0
    SOPC_Array* pFilePaths = NULL;
460
0
    SOPC_CertificateList* pCerts = NULL;
461
0
    SOPC_CRLList* pCrl = NULL;
462
0
    char* pFilePath = NULL;
463
    /* Get the array of path from basePath */
464
0
    SOPC_FileSystem_GetDirResult dirRes = SOPC_FileSystem_GetDirFilePaths(basePath, &pFilePaths);
465
0
    if (SOPC_FileSystem_GetDir_OK != dirRes)
466
0
    {
467
0
        if (!bDefaultBuild)
468
0
        {
469
0
            SOPC_Logger_TraceWarning(SOPC_LOG_MODULE_COMMON, "> PKI creation warning: failed to open directory <%s>.",
470
0
                                     basePath);
471
0
        }
472
0
        else
473
0
        {
474
0
            SOPC_Logger_TraceError(SOPC_LOG_MODULE_COMMON, "> PKI creation error: failed to open directory <%s>.",
475
0
                                   basePath);
476
0
        }
477
0
        return SOPC_STATUS_NOK;
478
0
    }
479
    /* Get the size and iterate for each item */
480
0
    size_t nbFiles = SOPC_Array_Size(pFilePaths);
481
0
    for (size_t idx = 0; idx < nbFiles && SOPC_STATUS_OK == status; idx++)
482
0
    {
483
0
        pFilePath = SOPC_Array_Get(pFilePaths, char*, idx);
484
0
        if (ignore_filtered_file(pFilePath))
485
0
        {
486
0
            SOPC_Logger_TraceDebug(SOPC_LOG_MODULE_COMMON, "> PKI ignoring file <%s>", pFilePath);
487
0
        }
488
0
        else
489
0
        {
490
0
            SOPC_Logger_TraceDebug(SOPC_LOG_MODULE_COMMON, "> PKI loading file <%s>", pFilePath);
491
492
0
            if (bIscrl)
493
0
            {
494
                /* Load CRL */
495
0
                status = SOPC_KeyManager_CRL_CreateOrAddFromFile(pFilePath, &pCrl);
496
0
            }
497
0
            else
498
0
            {
499
                /* Load CERT */
500
0
                status = SOPC_KeyManager_Certificate_CreateOrAddFromFile(pFilePath, &pCerts);
501
0
            }
502
0
        }
503
0
    }
504
    /* Clear in case of error */
505
0
    if (SOPC_STATUS_OK != status)
506
0
    {
507
0
        SOPC_KeyManager_Certificate_Free(pCerts);
508
0
        SOPC_KeyManager_CRL_Free(pCrl);
509
0
    }
510
0
    else
511
0
    {
512
0
        if (bIscrl)
513
0
        {
514
0
            *ppCrl = pCrl;
515
0
        }
516
0
        else
517
0
        {
518
0
            *ppCerts = pCerts;
519
0
        }
520
0
    }
521
    /* Always clear */
522
0
    SOPC_Array_Delete(pFilePaths);
523
0
    return status;
524
0
}
525
526
static SOPC_ReturnStatus sopc_pki_load_certificate_and_crl_list_from_store(const char* basePath,
527
                                                                           SOPC_CertificateList** ppTrustedCerts,
528
                                                                           SOPC_CRLList** ppTrustedCrl,
529
                                                                           SOPC_CertificateList** ppIssuerCerts,
530
                                                                           SOPC_CRLList** ppIssuerCrl,
531
                                                                           bool bDefaultBuild)
532
0
{
533
0
    SOPC_ASSERT(NULL != basePath);
534
0
    SOPC_ASSERT(NULL != ppTrustedCerts);
535
0
    SOPC_ASSERT(NULL != ppTrustedCrl);
536
0
    SOPC_ASSERT(NULL != ppIssuerCerts);
537
0
    SOPC_ASSERT(NULL != ppIssuerCrl);
538
    /* Trusted Certs */
539
0
    char* trustedCertsPath = NULL;
540
0
    SOPC_ReturnStatus status = SOPC_StrConcat(basePath, STR_TRUSTED_CERTS, &trustedCertsPath);
541
0
    if (SOPC_STATUS_OK == status)
542
0
    {
543
0
        status = load_certificate_or_crl_list(trustedCertsPath, ppTrustedCerts, NULL, false, bDefaultBuild);
544
0
    }
545
0
    SOPC_Free(trustedCertsPath);
546
    /* Trusted Crl */
547
0
    if (SOPC_STATUS_OK == status)
548
0
    {
549
0
        char* trustedCrlPath = NULL;
550
0
        status = SOPC_StrConcat(basePath, STR_TRUSTED_CRL, &trustedCrlPath);
551
0
        if (SOPC_STATUS_OK == status)
552
0
        {
553
0
            status = load_certificate_or_crl_list(trustedCrlPath, NULL, ppTrustedCrl, true, bDefaultBuild);
554
0
        }
555
0
        SOPC_Free(trustedCrlPath);
556
0
    }
557
    /* Issuer Certs */
558
0
    if (SOPC_STATUS_OK == status)
559
0
    {
560
0
        char* issuerCertsPath = NULL;
561
0
        status = SOPC_StrConcat(basePath, STR_ISSUERS_CERTS, &issuerCertsPath);
562
0
        if (SOPC_STATUS_OK == status)
563
0
        {
564
0
            status = load_certificate_or_crl_list(issuerCertsPath, ppIssuerCerts, NULL, false, bDefaultBuild);
565
0
        }
566
0
        SOPC_Free(issuerCertsPath);
567
0
    }
568
    /* Issuer Crl */
569
0
    if (SOPC_STATUS_OK == status)
570
0
    {
571
0
        char* issuerCrlPath = NULL;
572
0
        status = SOPC_StrConcat(basePath, STR_ISSUERS_CRL, &issuerCrlPath);
573
0
        if (SOPC_STATUS_OK == status)
574
0
        {
575
0
            status = load_certificate_or_crl_list(issuerCrlPath, NULL, ppIssuerCrl, true, bDefaultBuild);
576
0
        }
577
0
        SOPC_Free(issuerCrlPath);
578
0
    }
579
580
0
    if (SOPC_STATUS_OK != status)
581
0
    {
582
0
        SOPC_KeyManager_Certificate_Free(*ppTrustedCerts);
583
0
        SOPC_KeyManager_Certificate_Free(*ppIssuerCerts);
584
0
        SOPC_KeyManager_CRL_Free(*ppTrustedCrl);
585
0
        SOPC_KeyManager_CRL_Free(*ppIssuerCrl);
586
0
        *ppTrustedCerts = NULL;
587
0
        *ppIssuerCerts = NULL;
588
0
        *ppTrustedCrl = NULL;
589
0
        *ppIssuerCrl = NULL;
590
0
    }
591
0
    return status;
592
0
}
593
594
static bool pki_updated_trust_list_dir_exists(const char* path)
595
0
{
596
0
    SOPC_Array* pFilePaths = NULL;
597
0
    SOPC_FileSystem_GetDirResult dirRes = SOPC_FileSystem_GetDirFilePaths(path, &pFilePaths);
598
0
    SOPC_Array_Delete(pFilePaths);
599
0
    return (SOPC_FileSystem_GetDir_OK == dirRes);
600
0
}
601
602
static SOPC_ReturnStatus pki_create_from_store(
603
    const char* directoryStorePath,
604
    bool bDefaultBuild, /* If true load the root PKI directory without trust list update,
605
                         if false try to load the updated trust list subdirectory.*/
606
    SOPC_PKIProvider** ppPKI)
607
0
{
608
0
    SOPC_ASSERT(NULL != directoryStorePath);
609
0
    SOPC_ASSERT(NULL != ppPKI);
610
611
0
    SOPC_ReturnStatus status = SOPC_STATUS_OK;
612
0
    SOPC_CertificateList* pTrustedCerts = NULL; /* trusted intermediate CA + trusted certificates */
613
0
    SOPC_CertificateList* pIssuerCerts = NULL;  /* issuer intermediate CA */
614
0
    SOPC_CRLList* pTrustedCrl = NULL;           /* CRLs of trusted intermediate CA and trusted root CA */
615
0
    SOPC_CRLList* pIssuerCrl = NULL;            /* CRLs of issuer intermediate CA and issuer root CA */
616
0
    const char* basePath = NULL;
617
0
    char* path = NULL;
618
0
    char* trust_list_name = NULL;
619
620
    /* Select the right folder: add updateTrustList subdirectory path containing PKI update*/
621
0
    if (!bDefaultBuild)
622
0
    {
623
0
        status = SOPC_StrConcat(directoryStorePath, STR_TRUSTLIST_NAME, &path);
624
0
        if (SOPC_STATUS_OK != status)
625
0
        {
626
0
            return status;
627
0
        }
628
0
        if (pki_updated_trust_list_dir_exists(path))
629
0
        {
630
0
            basePath = path;
631
0
        }
632
0
        else
633
0
        {
634
0
            SOPC_Free(path);
635
0
            path = NULL;
636
0
            status = SOPC_STATUS_WOULD_BLOCK;
637
0
        }
638
0
    }
639
0
    else
640
0
    {
641
0
        basePath = directoryStorePath;
642
0
    }
643
    /* Load the files from the directory Store path */
644
0
    if (SOPC_STATUS_OK == status)
645
0
    {
646
0
        status = sopc_pki_load_certificate_and_crl_list_from_store(basePath, &pTrustedCerts, &pTrustedCrl,
647
0
                                                                   &pIssuerCerts, &pIssuerCrl, bDefaultBuild);
648
0
    }
649
    /* Check if the trustList is empty */
650
0
    if (SOPC_STATUS_OK == status && NULL == pTrustedCerts && NULL == pTrustedCrl && NULL == pIssuerCerts &&
651
0
        NULL == pIssuerCrl)
652
0
    {
653
0
        status = SOPC_STATUS_NOK;
654
0
        if (!bDefaultBuild)
655
0
        {
656
0
            SOPC_Logger_TraceWarning(SOPC_LOG_MODULE_COMMON, "> PKI creation warning: certificate store is empty (%s).",
657
0
                                     path);
658
0
        }
659
0
        else
660
0
        {
661
0
            SOPC_Logger_TraceError(SOPC_LOG_MODULE_COMMON, "> PKI creation error: certificate store is empty (%s).",
662
0
                                   path);
663
0
        }
664
0
    }
665
0
    if (SOPC_STATUS_OK == status)
666
0
    {
667
0
        status = SOPC_PKIProvider_CreateFromList(pTrustedCerts, pTrustedCrl, pIssuerCerts, pIssuerCrl, ppPKI);
668
0
    }
669
    /* if error then try with trusted and issuers folder. */
670
0
    if (!bDefaultBuild && SOPC_STATUS_OK != status)
671
0
    {
672
0
        SOPC_Logger_TraceInfo(SOPC_LOG_MODULE_COMMON,
673
0
                              "> PKI creation: loading PKI store root directory %s content (default behavior).",
674
0
                              directoryStorePath);
675
0
        SOPC_Logger_TraceInfo(SOPC_LOG_MODULE_COMMON,
676
0
                              "> PKI creation: the updated PKI store subdirectory %s%s is absent"
677
0
                              " or its content cannot be loaded (see warnings in this case).",
678
0
                              directoryStorePath, STR_TRUSTLIST_NAME);
679
0
        status = pki_create_from_store(directoryStorePath, true, ppPKI);
680
0
    }
681
    /* Copy the directoryStorePath */
682
0
    if (SOPC_STATUS_OK == status)
683
0
    {
684
        /* Copy only if not done during the recursive call. */
685
0
        if (NULL == (*ppPKI)->directoryStorePath)
686
0
        {
687
0
            (*ppPKI)->directoryStorePath = SOPC_strdup(directoryStorePath);
688
0
            if (NULL == (*ppPKI)->directoryStorePath)
689
0
            {
690
0
                SOPC_PKIProvider_Free(ppPKI);
691
0
                *ppPKI = NULL;
692
0
                status = SOPC_STATUS_OUT_OF_MEMORY;
693
0
            }
694
0
        }
695
0
    }
696
697
    /* Clear */
698
0
    SOPC_Free(path);
699
0
    SOPC_Free(trust_list_name);
700
701
0
    SOPC_KeyManager_Certificate_Free(pTrustedCerts);
702
0
    SOPC_KeyManager_Certificate_Free(pIssuerCerts);
703
0
    SOPC_KeyManager_CRL_Free(pTrustedCrl);
704
0
    SOPC_KeyManager_CRL_Free(pIssuerCrl);
705
706
0
    return status;
707
0
}
708
709
static SOPC_ReturnStatus sopc_pki_get_list_length(const SOPC_CertificateList* pTrustedCerts,
710
                                                  const SOPC_CRLList* pTrustedCrl,
711
                                                  const SOPC_CertificateList* pIssuerCerts,
712
                                                  const SOPC_CRLList* pIssuerCrl,
713
                                                  uint32_t* listLength)
714
0
{
715
0
    *listLength = 0;
716
0
    size_t lenTrustedCerts = 0;
717
0
    size_t lenTrustedCrl = 0;
718
0
    size_t lenIssuerCerts = 0;
719
0
    size_t lenIssuerCrl = 0;
720
0
    size_t lenTot = 0;
721
0
    SOPC_ReturnStatus status = SOPC_STATUS_OK;
722
0
    if (NULL != pTrustedCerts)
723
0
    {
724
0
        status = SOPC_KeyManager_Certificate_GetListLength(pTrustedCerts, &lenTrustedCerts);
725
0
    }
726
0
    if (NULL != pTrustedCrl && SOPC_STATUS_OK == status)
727
0
    {
728
0
        status = SOPC_KeyManager_CRL_GetListLength(pTrustedCrl, &lenTrustedCrl);
729
0
    }
730
0
    if (NULL != pIssuerCerts && SOPC_STATUS_OK == status)
731
0
    {
732
0
        status = SOPC_KeyManager_Certificate_GetListLength(pIssuerCerts, &lenIssuerCerts);
733
0
    }
734
0
    if (NULL != pIssuerCrl && SOPC_STATUS_OK == status)
735
0
    {
736
0
        status = SOPC_KeyManager_CRL_GetListLength(pIssuerCrl, &lenIssuerCrl);
737
0
    }
738
0
    if (SOPC_STATUS_OK == status)
739
0
    {
740
0
        lenTot = lenTrustedCerts + lenTrustedCrl + lenIssuerCerts + lenIssuerCrl;
741
0
        if (UINT32_MAX < lenTot)
742
0
        {
743
0
            status = SOPC_STATUS_INVALID_STATE;
744
0
        }
745
0
        else
746
0
        {
747
0
            *listLength = (uint32_t) lenTot;
748
0
        }
749
0
    }
750
0
    return status;
751
0
}
752
753
static SOPC_ReturnStatus sopc_pki_merge_crls(SOPC_CRLList* pLeft, SOPC_CRLList* pRight, SOPC_CRLList** ppRes)
754
0
{
755
0
    SOPC_ReturnStatus status = SOPC_STATUS_OK;
756
0
    if (NULL == ppRes)
757
0
    {
758
0
        return SOPC_STATUS_INVALID_PARAMETERS;
759
0
    }
760
0
    SOPC_CRLList* pRes = *ppRes;
761
    /* Left part */
762
0
    if (NULL != pLeft)
763
0
    {
764
0
        status = SOPC_KeyManager_CRL_Copy(pLeft, &pRes);
765
0
    }
766
    /* Right part */
767
0
    if (NULL != pRight && SOPC_STATUS_OK == status)
768
0
    {
769
0
        status = SOPC_KeyManager_CRL_Copy(pRight, &pRes);
770
0
    }
771
    /* clear if error */
772
0
    if (SOPC_STATUS_OK != status)
773
0
    {
774
0
        SOPC_KeyManager_CRL_Free(pRes);
775
0
        pRes = NULL;
776
0
    }
777
0
    *ppRes = pRes;
778
0
    return status;
779
0
}
780
781
static SOPC_ReturnStatus sopc_pki_remove_cert_by_thumbprint(SOPC_CertificateList** ppList,
782
                                                            SOPC_CRLList** ppCRLList,
783
                                                            const char* pThumbprint,
784
                                                            const char* listName,
785
                                                            bool* pbIsRemoved,
786
                                                            bool* pbIsIssuer)
787
0
{
788
0
    SOPC_ASSERT(NULL != ppList);
789
0
    SOPC_ASSERT(NULL != ppCRLList);
790
0
    SOPC_ASSERT(NULL != pThumbprint);
791
0
    SOPC_ASSERT(NULL != pbIsRemoved);
792
0
    SOPC_ASSERT(NULL != pbIsIssuer);
793
794
0
    size_t lenThumb = strlen(pThumbprint);
795
0
    SOPC_ASSERT(HEX_THUMBPRINT_SIZE == lenThumb);
796
797
    /* Initialized the value to return */
798
0
    *pbIsRemoved = false;
799
0
    *pbIsIssuer = false;
800
0
    SOPC_ReturnStatus status = SOPC_STATUS_OK;
801
802
0
    if (NULL == *ppList)
803
0
    {
804
        /* the certificate list is empty, do nothing*/
805
0
        return SOPC_STATUS_OK;
806
0
    }
807
808
0
    uint32_t count = 0;
809
0
    bool bIsIssuer = false;
810
0
    bool bAtLeastOneIssuer = false;
811
0
    bool bAtLeastOne = false;
812
813
0
    bool bCertIsRemoved = true;
814
0
    while (bCertIsRemoved && SOPC_STATUS_OK == status)
815
0
    {
816
0
        status = SOPC_KeyManager_CertificateList_RemoveCertFromSHA1(ppList, ppCRLList, pThumbprint, &bCertIsRemoved,
817
0
                                                                    &bIsIssuer);
818
0
        if (bCertIsRemoved)
819
0
        {
820
0
            if (bIsIssuer)
821
0
            {
822
0
                bAtLeastOneIssuer = true;
823
0
            }
824
0
            if (bAtLeastOneIssuer && !bIsIssuer)
825
0
            {
826
0
                SOPC_Logger_TraceWarning(SOPC_LOG_MODULE_COMMON,
827
0
                                         "> PKI remove: certificate thumbprint <%s> has been found both as CA and as "
828
0
                                         "leaf certificate from %s",
829
0
                                         pThumbprint, listName);
830
0
            }
831
0
            bAtLeastOne = true;
832
0
            count = count + 1;
833
0
        }
834
0
    }
835
836
0
    if (bAtLeastOne && NULL != listName)
837
0
    {
838
0
        SOPC_Logger_TraceDebug(SOPC_LOG_MODULE_COMMON,
839
0
                               "> PKI remove: certificate thumbprint <%s> has been removed (%" PRIu32 " times) from %s",
840
0
                               pThumbprint, count, listName);
841
0
    }
842
843
0
    *pbIsIssuer = bAtLeastOneIssuer;
844
0
    *pbIsRemoved = bAtLeastOne;
845
0
    return status;
846
0
}
847
848
static SOPC_ReturnStatus sopc_pki_check_lists(SOPC_CertificateList* pTrustedCerts,
849
                                              SOPC_CertificateList* pIssuerCerts,
850
                                              SOPC_CRLList* pTrustedCrl,
851
                                              SOPC_CRLList* pIssuerCrl,
852
                                              bool* bTrustedCaFound,
853
                                              bool* bIssuerCaFound)
854
0
{
855
0
    SOPC_ReturnStatus status = SOPC_STATUS_OK;
856
    /* Trusted stats */
857
0
    uint32_t trusted_ca_count = 0;
858
0
    uint32_t trusted_list_length = 0;
859
0
    uint32_t issued_cert_count = 0;
860
0
    uint32_t trusted_root_count = 0;
861
    /* Issuer stats */
862
0
    uint32_t issuer_ca_count = 0;
863
0
    uint32_t issuer_list_length = 0;
864
0
    uint32_t issuer_root_count = 0;
865
0
    *bTrustedCaFound = false;
866
0
    *bIssuerCaFound = false;
867
868
0
    if (NULL == pTrustedCerts)
869
0
    {
870
0
        SOPC_Logger_TraceError(SOPC_LOG_MODULE_COMMON, "> PKI creation error: no trusted certificate is provided.");
871
0
        return SOPC_STATUS_INVALID_PARAMETERS;
872
0
    }
873
0
    SOPC_PKIProviderInternal_GetListStats(pTrustedCerts, &trusted_ca_count, &trusted_list_length, &trusted_root_count);
874
0
    issued_cert_count = trusted_list_length - trusted_ca_count;
875
    /* trusted CA => trusted CRL*/
876
0
    if (0 != trusted_ca_count && NULL == pTrustedCrl)
877
0
    {
878
0
        SOPC_Logger_TraceWarning(SOPC_LOG_MODULE_COMMON,
879
0
                                 "> PKI creation warning: trusted CA certificates are provided but no CRL.");
880
0
    }
881
0
    SOPC_PKIProviderInternal_GetListStats(pIssuerCerts, &issuer_ca_count, &issuer_list_length, &issuer_root_count);
882
    /* issuer CA => issuer CRL*/
883
0
    if (0 != issuer_ca_count && NULL == pIssuerCrl)
884
0
    {
885
0
        SOPC_Logger_TraceWarning(SOPC_LOG_MODULE_COMMON,
886
0
                                 "> PKI creation warning: issuer CA certificates are provided but no CRL.");
887
0
    }
888
    /* Check if issuerCerts list is only filled with CA. */
889
0
    if (issuer_list_length != issuer_ca_count)
890
0
    {
891
0
        SOPC_Logger_TraceError(SOPC_LOG_MODULE_COMMON, "> PKI creation error: not all issuer certificates are CAs.");
892
0
        return SOPC_STATUS_INVALID_PARAMETERS;
893
0
    }
894
    /* check and warn in case no roots is provided wheras at least one trusted leaf certificate is provided. */
895
0
    if ((0 == issuer_root_count) && (0 == trusted_root_count) && (0 != issued_cert_count))
896
0
    {
897
        /* In this case, only trusted self-signed leaf certificates will be accepted. */
898
0
        SOPC_Logger_TraceWarning(SOPC_LOG_MODULE_COMMON,
899
0
                                 "> PKI creation warning: no root (CA) defined: only trusted self-signed leaf "
900
0
                                 "certificates will be accepted without possibility to revoke them (no CRL).");
901
0
    }
902
0
    *bTrustedCaFound = 0 != trusted_ca_count;
903
0
    *bIssuerCaFound = 0 != issuer_ca_count;
904
0
    return status;
905
0
}
906
907
static SOPC_ReturnStatus sopc_pki_check_list_length(SOPC_PKIProvider* pPKI,
908
                                                    SOPC_CertificateList* pTrustedCerts,
909
                                                    SOPC_CRLList* pTrustedCrl,
910
                                                    SOPC_CertificateList* pIssuerCerts,
911
                                                    SOPC_CRLList* pIssuerCrl,
912
                                                    const bool bIncludeExistingList)
913
0
{
914
0
    SOPC_ASSERT(NULL != pPKI);
915
0
    uint32_t PKILen = 0;
916
0
    uint32_t updateLen = 0;
917
0
    SOPC_ReturnStatus status = SOPC_STATUS_OK;
918
0
    if (bIncludeExistingList)
919
0
    {
920
0
        status = sopc_pki_get_list_length(pPKI->pTrustedCerts, pPKI->pTrustedCrl, pPKI->pIssuerCerts, pPKI->pIssuerCrl,
921
0
                                          &PKILen);
922
0
    }
923
0
    if (SOPC_STATUS_OK == status)
924
0
    {
925
0
        status = sopc_pki_get_list_length(pTrustedCerts, pTrustedCrl, pIssuerCerts, pIssuerCrl, &updateLen);
926
0
    }
927
0
    if (SOPC_STATUS_OK != status)
928
0
    {
929
0
        return status;
930
0
    }
931
0
    if (SOPC_PKI_MAX_NB_CERT_AND_CRL < PKILen + updateLen)
932
0
    {
933
0
        SOPC_Logger_TraceError(SOPC_LOG_MODULE_COMMON,
934
0
                               "> PKI creation error: too many (%" PRIu32
935
0
                               ") certificates and CRLs. The maximum configured is %" PRIu32
936
0
                               ", please change SOPC_PKI_MAX_NB_CERT_AND_CRL",
937
0
                               PKILen + updateLen, (uint32_t) SOPC_PKI_MAX_NB_CERT_AND_CRL);
938
0
    }
939
0
    return status;
940
0
}
941
942
static SOPC_ReturnStatus sopc_pki_validate_anything(SOPC_PKIProvider* pPKI,
943
                                                    const SOPC_CertificateList* pToValidate,
944
                                                    const SOPC_PKI_Profile* pProfile,
945
                                                    uint32_t* error,
946
                                                    SOPC_PKI_Cert_Failure_Context* context)
947
0
{
948
0
    SOPC_UNUSED_ARG(pPKI);
949
0
    SOPC_UNUSED_ARG(pToValidate);
950
0
    SOPC_UNUSED_ARG(pProfile);
951
0
    SOPC_UNUSED_ARG(error);
952
0
    SOPC_UNUSED_ARG(context);
953
0
    return SOPC_STATUS_OK;
954
0
}
955
956
0
#define NB_PROFILES (sizeof(g_all_profiles) / sizeof(*g_all_profiles))
957
958
static const SOPC_PKI_ChainProfile* sopc_pki_get_chain_profile_from_security_policy(const char* uri)
959
0
{
960
0
    if (NULL == uri)
961
0
    {
962
0
        return NULL;
963
0
    }
964
965
0
    const size_t len = strlen(uri) + 1;
966
0
    for (size_t i = 0; i < NB_PROFILES; ++i)
967
0
    {
968
0
        const struct Profile_Cfg* pProfile = &g_all_profiles[i];
969
0
        const SOPC_SecurityPolicy_Config* pPolicy = SOPC_SecurityPolicy_Config_Get(pProfile->id);
970
0
        const char* pUri = pPolicy->uri;
971
0
        if (pUri != NULL && SOPC_strncmp_ignore_case(uri, pUri, len) == 0)
972
0
        {
973
0
            return pProfile->chain;
974
0
        }
975
0
    }
976
977
0
    return NULL;
978
0
}
979
980
static const SOPC_PKI_LeafProfile* sopc_pki_get_leaf_profile_from_security_policy(const char* uri)
981
0
{
982
0
    if (NULL == uri)
983
0
    {
984
0
        return NULL;
985
0
    }
986
987
0
    const size_t len = strlen(uri) + 1;
988
0
    for (size_t i = 0; i < NB_PROFILES; ++i)
989
0
    {
990
0
        const struct Profile_Cfg* pProfile = &g_all_profiles[i];
991
0
        const SOPC_SecurityPolicy_Config* pPolicy = SOPC_SecurityPolicy_Config_Get(pProfile->id);
992
0
        const char* pUri = pPolicy->uri;
993
0
        if (pUri != NULL && SOPC_strncmp_ignore_case(uri, pUri, len) == 0)
994
0
        {
995
0
            return pProfile->leaf;
996
0
        }
997
0
    }
998
0
    return NULL;
999
0
}
1000
1001
#endif /* WITH_NO_CRYPTO */
1002
1003
/**
1004
 * End of static functions definition
1005
 *
1006
 */
1007
1008
SOPC_ReturnStatus SOPC_PKIProvider_CreateLeafProfile(const char* securityPolicyUri, SOPC_PKI_LeafProfile** ppProfile)
1009
0
{
1010
#ifdef WITH_NO_CRYPTO
1011
    SOPC_UNUSED_ARG(securityPolicyUri);
1012
    SOPC_UNUSED_ARG(ppProfile);
1013
    return SOPC_STATUS_NOT_SUPPORTED;
1014
#else
1015
0
    if (NULL == ppProfile)
1016
0
    {
1017
0
        return SOPC_STATUS_INVALID_PARAMETERS;
1018
0
    }
1019
0
    const SOPC_PKI_LeafProfile* pProfileRef = NULL;
1020
0
    if (NULL != securityPolicyUri)
1021
0
    {
1022
0
        pProfileRef = sopc_pki_get_leaf_profile_from_security_policy(securityPolicyUri);
1023
0
        if (NULL == pProfileRef)
1024
0
        {
1025
0
            return SOPC_STATUS_INVALID_PARAMETERS;
1026
0
        }
1027
0
    }
1028
0
    SOPC_PKI_LeafProfile* pProfile = SOPC_Calloc(1, sizeof(SOPC_PKI_LeafProfile));
1029
0
    if (NULL == pProfile)
1030
0
    {
1031
0
        return SOPC_STATUS_OUT_OF_MEMORY;
1032
0
    }
1033
1034
0
    if (NULL != securityPolicyUri)
1035
0
    {
1036
0
        *pProfile = *pProfileRef;
1037
0
    }
1038
1039
0
    *ppProfile = pProfile;
1040
0
    return SOPC_STATUS_OK;
1041
0
#endif
1042
0
}
1043
1044
SOPC_ReturnStatus SOPC_PKIProvider_LeafProfileSetUsageFromType(SOPC_PKI_LeafProfile* pProfile, SOPC_PKI_Type PKIType)
1045
0
{
1046
#ifdef WITH_NO_CRYPTO
1047
    SOPC_UNUSED_ARG(pProfile);
1048
    SOPC_UNUSED_ARG(PKIType);
1049
    return SOPC_STATUS_NOT_SUPPORTED;
1050
#else
1051
0
    if (NULL == pProfile)
1052
0
    {
1053
0
        return SOPC_STATUS_INVALID_PARAMETERS;
1054
0
    }
1055
0
    switch (PKIType)
1056
0
    {
1057
0
    case SOPC_PKI_TYPE_CLIENT_APP:
1058
0
        pProfile->keyUsage = g_appKU;
1059
0
        pProfile->extendedKeyUsage = g_clientEKU;
1060
0
        break;
1061
0
    case SOPC_PKI_TYPE_SERVER_APP:
1062
0
        pProfile->keyUsage = g_appKU;
1063
0
        pProfile->extendedKeyUsage = g_serverEKU;
1064
0
        break;
1065
0
    case SOPC_PKI_TYPE_USER:
1066
0
        pProfile->keyUsage = g_usrKU;
1067
0
        pProfile->extendedKeyUsage = g_userEKU;
1068
0
        break;
1069
0
    default:
1070
0
        return SOPC_STATUS_INVALID_PARAMETERS;
1071
0
    }
1072
0
    return SOPC_STATUS_OK;
1073
0
#endif
1074
0
}
1075
1076
SOPC_ReturnStatus SOPC_PKIProvider_LeafProfileSetURI(SOPC_PKI_LeafProfile* pProfile, const char* applicationUri)
1077
0
{
1078
#ifdef WITH_NO_CRYPTO
1079
    SOPC_UNUSED_ARG(pProfile);
1080
    SOPC_UNUSED_ARG(applicationUri);
1081
    return SOPC_STATUS_NOT_SUPPORTED;
1082
#else
1083
0
    if (NULL == pProfile || NULL == applicationUri)
1084
0
    {
1085
0
        return SOPC_STATUS_INVALID_PARAMETERS;
1086
0
    }
1087
0
    if (NULL != pProfile->sanApplicationUri)
1088
0
    {
1089
0
        return SOPC_STATUS_INVALID_STATE;
1090
0
    }
1091
0
    pProfile->sanApplicationUri = SOPC_strdup(applicationUri);
1092
0
    if (NULL == pProfile->sanApplicationUri)
1093
0
    {
1094
0
        return SOPC_STATUS_OUT_OF_MEMORY;
1095
0
    }
1096
0
    return SOPC_STATUS_OK;
1097
0
#endif
1098
0
}
1099
1100
SOPC_ReturnStatus SOPC_PKIProvider_LeafProfileSetURL(SOPC_PKI_LeafProfile* pProfile, const char* url)
1101
0
{
1102
#ifdef WITH_NO_CRYPTO
1103
    SOPC_UNUSED_ARG(pProfile);
1104
    SOPC_UNUSED_ARG(url);
1105
    return SOPC_STATUS_NOT_SUPPORTED;
1106
#else
1107
0
    if (NULL == pProfile || NULL == url)
1108
0
    {
1109
0
        return SOPC_STATUS_INVALID_PARAMETERS;
1110
0
    }
1111
0
    if (NULL != pProfile->sanURL)
1112
0
    {
1113
0
        return SOPC_STATUS_INVALID_STATE;
1114
0
    }
1115
0
    pProfile->sanURL = SOPC_strdup(url);
1116
0
    if (NULL == pProfile->sanURL)
1117
0
    {
1118
0
        return SOPC_STATUS_OUT_OF_MEMORY;
1119
0
    }
1120
0
    return SOPC_STATUS_OK;
1121
0
#endif
1122
0
}
1123
1124
SOPC_ReturnStatus SOPC_PKIProvider_ProfileSetURI(SOPC_PKI_Profile* pProfile, const char* applicationUri)
1125
0
{
1126
0
    return SOPC_PKIProvider_LeafProfileSetURI(pProfile->leafProfile, applicationUri);
1127
0
}
1128
1129
SOPC_ReturnStatus SOPC_PKIProvider_ProfileSetURL(SOPC_PKI_Profile* pProfile, const char* url)
1130
0
{
1131
0
    return SOPC_PKIProvider_LeafProfileSetURL(pProfile->leafProfile, url);
1132
0
}
1133
1134
void SOPC_PKIProvider_DeleteLeafProfile(SOPC_PKI_LeafProfile** ppProfile)
1135
0
{
1136
#ifdef WITH_NO_CRYPTO
1137
    SOPC_UNUSED_ARG(ppProfile);
1138
#else
1139
0
    if (NULL == ppProfile)
1140
0
    {
1141
0
        return;
1142
0
    }
1143
0
    SOPC_PKI_LeafProfile* pProfile = *ppProfile;
1144
0
    if (NULL != pProfile)
1145
0
    {
1146
0
        SOPC_Free(pProfile->sanApplicationUri);
1147
0
        SOPC_Free(pProfile->sanURL);
1148
0
        SOPC_Free(pProfile);
1149
0
        *ppProfile = NULL;
1150
0
    }
1151
0
#endif
1152
0
}
1153
1154
SOPC_ReturnStatus SOPC_PKIProvider_CreateProfile(const char* securityPolicyUri, SOPC_PKI_Profile** ppProfile)
1155
0
{
1156
#ifdef WITH_NO_CRYPTO
1157
    SOPC_UNUSED_ARG(securityPolicyUri);
1158
    SOPC_UNUSED_ARG(ppProfile);
1159
    return SOPC_STATUS_NOT_SUPPORTED;
1160
#else
1161
0
    if (NULL == ppProfile || NULL == securityPolicyUri)
1162
0
    {
1163
0
        return SOPC_STATUS_INVALID_PARAMETERS;
1164
0
    }
1165
0
    const SOPC_PKI_ChainProfile* pChainProfileRef = sopc_pki_get_chain_profile_from_security_policy(securityPolicyUri);
1166
0
    if (NULL == pChainProfileRef)
1167
0
    {
1168
0
        return SOPC_STATUS_INVALID_PARAMETERS;
1169
0
    }
1170
0
    SOPC_PKI_ChainProfile* pChainProfile = SOPC_Calloc(1, sizeof(SOPC_PKI_ChainProfile));
1171
0
    if (NULL == pChainProfile)
1172
0
    {
1173
0
        return SOPC_STATUS_OUT_OF_MEMORY;
1174
0
    }
1175
0
    *pChainProfile = *pChainProfileRef;
1176
1177
0
    SOPC_PKI_LeafProfile* pLeafProfile = NULL;
1178
0
    SOPC_PKI_Profile* pProfile = NULL;
1179
0
    SOPC_ReturnStatus status = SOPC_PKIProvider_CreateLeafProfile(securityPolicyUri, &pLeafProfile);
1180
0
    if (SOPC_STATUS_OK == status)
1181
0
    {
1182
0
        pProfile = SOPC_Calloc(1, sizeof(SOPC_PKI_Profile));
1183
0
        if (NULL == pProfile)
1184
0
        {
1185
0
            status = SOPC_STATUS_OUT_OF_MEMORY;
1186
0
        }
1187
0
    }
1188
0
    if (SOPC_STATUS_OK == status)
1189
0
    {
1190
0
        pProfile->leafProfile = pLeafProfile;
1191
0
        pProfile->chainProfile = pChainProfile;
1192
0
        pProfile->bBackwardInteroperability = true;
1193
0
        pProfile->bApplyLeafProfile = true;
1194
0
    }
1195
0
    else
1196
0
    {
1197
0
        SOPC_Free(pChainProfile);
1198
0
        SOPC_PKIProvider_DeleteLeafProfile(&pLeafProfile);
1199
0
    }
1200
0
    *ppProfile = pProfile;
1201
0
    return SOPC_STATUS_OK;
1202
0
#endif
1203
0
}
1204
1205
SOPC_ReturnStatus SOPC_PKIProvider_ProfileSetUsageFromType(SOPC_PKI_Profile* pProfile, SOPC_PKI_Type PKIType)
1206
0
{
1207
#ifdef WITH_NO_CRYPTO
1208
    SOPC_UNUSED_ARG(pProfile);
1209
    SOPC_UNUSED_ARG(PKIType);
1210
    return SOPC_STATUS_NOT_SUPPORTED;
1211
#else
1212
0
    if (NULL == pProfile)
1213
0
    {
1214
0
        return SOPC_STATUS_INVALID_PARAMETERS;
1215
0
    }
1216
0
    SOPC_ReturnStatus status = SOPC_PKIProvider_LeafProfileSetUsageFromType(pProfile->leafProfile, PKIType);
1217
0
    if (SOPC_STATUS_OK != status)
1218
0
    {
1219
0
        return status;
1220
0
    }
1221
0
    switch (PKIType)
1222
0
    {
1223
0
    case SOPC_PKI_TYPE_CLIENT_APP:
1224
0
        pProfile->bApplyLeafProfile = true;
1225
0
        pProfile->bBackwardInteroperability = true;
1226
0
        break;
1227
0
    case SOPC_PKI_TYPE_SERVER_APP:
1228
0
        pProfile->bApplyLeafProfile = true;
1229
0
        pProfile->bBackwardInteroperability = true;
1230
0
        break;
1231
0
    case SOPC_PKI_TYPE_USER:
1232
0
        pProfile->bApplyLeafProfile = false;
1233
0
        pProfile->bBackwardInteroperability = false;
1234
0
        break;
1235
0
    default:
1236
0
        return SOPC_STATUS_INVALID_PARAMETERS;
1237
0
    }
1238
0
    return SOPC_STATUS_OK;
1239
0
#endif
1240
0
}
1241
1242
void SOPC_PKIProvider_DeleteProfile(SOPC_PKI_Profile** ppProfile)
1243
0
{
1244
#ifdef WITH_NO_CRYPTO
1245
    SOPC_UNUSED_ARG(ppProfile);
1246
#else
1247
0
    if (NULL == ppProfile)
1248
0
    {
1249
0
        return;
1250
0
    }
1251
0
    SOPC_PKI_Profile* pProfile = *ppProfile;
1252
0
    if (NULL != pProfile)
1253
0
    {
1254
0
        SOPC_Free(pProfile->chainProfile);
1255
0
        SOPC_PKIProvider_DeleteLeafProfile(&pProfile->leafProfile);
1256
0
        SOPC_Free(pProfile);
1257
0
        *ppProfile = NULL;
1258
0
    }
1259
0
#endif
1260
0
}
1261
1262
SOPC_ReturnStatus SOPC_PKIProvider_CreateMinimalUserProfile(SOPC_PKI_Profile** ppProfile)
1263
0
{
1264
#ifdef WITH_NO_CRYPTO
1265
    SOPC_UNUSED_ARG(ppProfile);
1266
    return SOPC_STATUS_NOT_SUPPORTED;
1267
#else
1268
    /* Minimal profile for the chain.
1269
    The leaf profile is not used for users during the validation process but the user certificate properties
1270
    are checked according to the security policy during the activate session */
1271
0
    if (NULL == ppProfile)
1272
0
    {
1273
0
        return SOPC_STATUS_INVALID_PARAMETERS;
1274
0
    }
1275
0
    SOPC_PKI_Profile* pProfile = NULL;
1276
0
    SOPC_ReturnStatus status = SOPC_PKIProvider_CreateProfile(SOPC_SecurityPolicy_Basic256Sha256_URI, &pProfile);
1277
0
    if (SOPC_STATUS_OK == status)
1278
0
    {
1279
0
        status = SOPC_PKIProvider_ProfileSetUsageFromType(pProfile, SOPC_PKI_TYPE_USER);
1280
0
    }
1281
0
    *ppProfile = pProfile;
1282
0
    return status;
1283
0
#endif
1284
0
}
1285
1286
SOPC_ReturnStatus SOPC_PKIProvider_CheckLeafCertificate(const SOPC_CertificateList* pToValidate,
1287
                                                        const SOPC_PKI_LeafProfile* pProfile,
1288
                                                        uint32_t* error,
1289
                                                        SOPC_PKI_Cert_Failure_Context* context)
1290
0
{
1291
#ifdef WITH_NO_CRYPTO
1292
    SOPC_UNUSED_ARG(pToValidate);
1293
    SOPC_UNUSED_ARG(pProfile);
1294
    SOPC_UNUSED_ARG(error);
1295
    SOPC_UNUSED_ARG(context);
1296
    return SOPC_STATUS_NOT_SUPPORTED;
1297
#else
1298
0
    if (NULL == pToValidate || NULL == pProfile || NULL == error)
1299
0
    {
1300
0
        return SOPC_STATUS_INVALID_PARAMETERS;
1301
0
    }
1302
1303
0
    *error = SOPC_CertificateValidationError_Unknown;
1304
0
    uint32_t firstError = SOPC_CertificateValidationError_Unknown;
1305
0
    uint32_t currentError = SOPC_CertificateValidationError_Unknown;
1306
0
    bool bErrorFound = false;
1307
0
    SOPC_ReturnStatus status = SOPC_STATUS_OK;
1308
0
    status = SOPC_PKIProvider_CheckCommonName(pToValidate);
1309
0
    if (SOPC_STATUS_OK != status)
1310
0
    {
1311
0
        firstError = SOPC_CertificateValidationError_Invalid;
1312
0
        bErrorFound = true;
1313
0
    }
1314
0
    if (pProfile->bApplySecurityPolicy)
1315
0
    {
1316
0
        status = SOPC_PKIProvider_CheckSecurityPolicy(pToValidate, pProfile);
1317
0
        if (SOPC_STATUS_OK != status)
1318
0
        {
1319
0
            currentError = SOPC_CertificateValidationError_PolicyCheckFailed;
1320
0
            if (!bErrorFound)
1321
0
            {
1322
0
                firstError = currentError;
1323
0
                bErrorFound = true;
1324
0
            }
1325
0
        }
1326
0
    }
1327
0
    if (NULL != pProfile->sanURL)
1328
0
    {
1329
0
        char** invalidHostname = (NULL != context ? &context->invalidHostname : NULL);
1330
0
        status = SOPC_PKIProvider_CheckHostName(pToValidate, pProfile->sanURL, invalidHostname);
1331
0
        if (SOPC_STATUS_OK != status)
1332
0
        {
1333
0
            currentError = SOPC_CertificateValidationError_HostNameInvalid;
1334
0
            if (!bErrorFound)
1335
0
            {
1336
0
                firstError = currentError;
1337
0
                bErrorFound = true;
1338
0
            }
1339
0
        }
1340
0
    }
1341
0
    if (NULL != pProfile->sanApplicationUri)
1342
0
    {
1343
0
        status = sopc_pki_check_application_uri(pToValidate, pProfile->sanApplicationUri);
1344
0
        if (SOPC_STATUS_OK != status)
1345
0
        {
1346
0
            currentError = SOPC_CertificateValidationError_UriInvalid;
1347
0
            if (!bErrorFound)
1348
0
            {
1349
0
                firstError = currentError;
1350
0
                bErrorFound = true;
1351
0
            }
1352
0
            if (NULL != context)
1353
0
            {
1354
0
                context->invalidURI = SOPC_strdup(pProfile->sanApplicationUri);
1355
0
            }
1356
0
        }
1357
0
    }
1358
0
    status = SOPC_PKIProvider_CheckCertificateUsage(pToValidate, pProfile);
1359
0
    if (SOPC_STATUS_OK != status)
1360
0
    {
1361
0
        currentError = SOPC_CertificateValidationError_UseNotAllowed;
1362
0
        if (!bErrorFound)
1363
0
        {
1364
0
            firstError = currentError;
1365
0
            bErrorFound = true;
1366
0
        }
1367
0
    }
1368
1369
0
    if (bErrorFound)
1370
0
    {
1371
0
        *error = firstError;
1372
0
        status = SOPC_STATUS_NOK;
1373
0
    }
1374
1375
0
    return status;
1376
0
#endif
1377
0
}
1378
1379
SOPC_ReturnStatus SOPC_PKIPermissive_Create(SOPC_PKIProvider** ppPKI)
1380
0
{
1381
#ifdef WITH_NO_CRYPTO
1382
    SOPC_UNUSED_ARG(ppPKI);
1383
    return SOPC_STATUS_NOT_SUPPORTED;
1384
#else
1385
0
    SOPC_PKIProvider* pPKI = NULL;
1386
1387
0
    if (NULL == ppPKI)
1388
0
    {
1389
0
        return SOPC_STATUS_INVALID_PARAMETERS;
1390
0
    }
1391
1392
0
    pPKI = SOPC_Calloc(1, sizeof(SOPC_PKIProvider));
1393
1394
0
    if (NULL == pPKI)
1395
0
    {
1396
0
        return SOPC_STATUS_OUT_OF_MEMORY;
1397
0
    }
1398
1399
0
    SOPC_ReturnStatus mutStatus = SOPC_Mutex_Initialization(&pPKI->mutex);
1400
0
    SOPC_ASSERT(SOPC_STATUS_OK == mutStatus);
1401
0
    pPKI->pTrustedRoots = NULL;
1402
0
    pPKI->pTrustedCerts = NULL;
1403
0
    pPKI->pTrustedCrl = NULL;
1404
0
    pPKI->pIssuerRoots = NULL;
1405
0
    pPKI->pIssuerCerts = NULL;
1406
0
    pPKI->pIssuerCrl = NULL;
1407
0
    pPKI->pAllCerts = NULL;
1408
0
    pPKI->pAllRoots = NULL;
1409
0
    pPKI->pAllCrl = NULL;
1410
0
    pPKI->pRejectedList = NULL;
1411
0
    pPKI->directoryStorePath = NULL;
1412
0
    pPKI->pFnValidateCert = &sopc_pki_validate_anything;
1413
0
    pPKI->pUpdateCb = NULL;
1414
0
    pPKI->updateCbParam = 0;
1415
0
    pPKI->isPermissive = true;
1416
0
    *ppPKI = pPKI;
1417
0
    return SOPC_STATUS_OK;
1418
0
#endif
1419
0
}
1420
1421
void SOPC_PKIProvider_Free(SOPC_PKIProvider** ppPKI)
1422
0
{
1423
#ifdef WITH_NO_CRYPTO
1424
    SOPC_UNUSED_ARG(ppPKI);
1425
#else
1426
0
    if (NULL == ppPKI || NULL == *ppPKI)
1427
0
    {
1428
0
        return;
1429
0
    }
1430
0
    sopc_pki_clear(*ppPKI);
1431
0
    SOPC_Free(*ppPKI);
1432
0
    *ppPKI = NULL;
1433
0
#endif
1434
0
}
1435
1436
SOPC_ReturnStatus SOPC_PKIProvider_SetStorePath(const char* directoryStorePath, SOPC_PKIProvider* pPKI)
1437
0
{
1438
#ifdef WITH_NO_CRYPTO
1439
    SOPC_UNUSED_ARG(directoryStorePath);
1440
    SOPC_UNUSED_ARG(pPKI);
1441
    return SOPC_STATUS_NOT_SUPPORTED;
1442
#else
1443
0
    if (NULL == pPKI || NULL == directoryStorePath)
1444
0
    {
1445
0
        return SOPC_STATUS_INVALID_PARAMETERS;
1446
0
    }
1447
1448
0
    SOPC_ReturnStatus status = SOPC_STATUS_OK;
1449
0
    SOPC_ReturnStatus mutStatus = SOPC_Mutex_Lock(&pPKI->mutex);
1450
0
    SOPC_ASSERT(SOPC_STATUS_OK == mutStatus);
1451
1452
    /* Create if necessary the store */
1453
0
    SOPC_FileSystem_CreationResult mkdir_res = SOPC_FileSystem_mkdir(directoryStorePath);
1454
0
    if (SOPC_FileSystem_Creation_Error_PathAlreadyExists != mkdir_res && SOPC_FileSystem_Creation_OK != mkdir_res)
1455
0
    {
1456
0
        status = SOPC_STATUS_INVALID_PARAMETERS;
1457
0
    }
1458
1459
0
    if (SOPC_STATUS_OK == status)
1460
0
    {
1461
        /* Copy the directory store path before exchange the data */
1462
0
        char* pCopyPath = SOPC_strdup(directoryStorePath);
1463
0
        if (NULL == pCopyPath)
1464
0
        {
1465
0
            status = SOPC_STATUS_NOK;
1466
0
        }
1467
0
        SOPC_Free(pPKI->directoryStorePath);
1468
0
        pPKI->directoryStorePath = pCopyPath;
1469
0
    }
1470
1471
0
    mutStatus = SOPC_Mutex_Unlock(&pPKI->mutex);
1472
0
    SOPC_ASSERT(SOPC_STATUS_OK == mutStatus);
1473
1474
0
    return status;
1475
0
#endif
1476
0
}
1477
1478
SOPC_ReturnStatus SOPC_PKIProvider_SetUpdateCb(SOPC_PKIProvider* pPKI,
1479
                                               SOPC_PKIProviderUpdateCb* pUpdateCb,
1480
                                               uintptr_t updateParam)
1481
0
{
1482
#ifdef WITH_NO_CRYPTO
1483
    SOPC_UNUSED_ARG(pPKI);
1484
    SOPC_UNUSED_ARG(pUpdateCb);
1485
    SOPC_UNUSED_ARG(updateParam);
1486
    return SOPC_STATUS_NOT_SUPPORTED;
1487
#else
1488
0
    if (NULL == pPKI || NULL == pUpdateCb)
1489
0
    {
1490
0
        return SOPC_STATUS_INVALID_PARAMETERS;
1491
0
    }
1492
0
    SOPC_ReturnStatus status = SOPC_STATUS_INVALID_STATE;
1493
0
    SOPC_ReturnStatus mutStatus = SOPC_Mutex_Lock(&pPKI->mutex);
1494
0
    SOPC_ASSERT(SOPC_STATUS_OK == mutStatus);
1495
0
    if (NULL == pPKI->pUpdateCb)
1496
0
    {
1497
0
        pPKI->pUpdateCb = pUpdateCb;
1498
0
        pPKI->updateCbParam = updateParam;
1499
0
        status = SOPC_STATUS_OK;
1500
0
    }
1501
0
    mutStatus = SOPC_Mutex_Unlock(&pPKI->mutex);
1502
0
    SOPC_ASSERT(SOPC_STATUS_OK == mutStatus);
1503
0
    return status;
1504
0
#endif
1505
0
}
1506
1507
SOPC_ReturnStatus SOPC_PKIProvider_WriteOrAppendToList(SOPC_PKIProvider* pPKI,
1508
                                                       SOPC_CertificateList** ppTrustedCerts,
1509
                                                       SOPC_CRLList** ppTrustedCrl,
1510
                                                       SOPC_CertificateList** ppIssuerCerts,
1511
                                                       SOPC_CRLList** ppIssuerCrl)
1512
0
{
1513
#ifdef WITH_NO_CRYPTO
1514
    SOPC_UNUSED_ARG(pPKI);
1515
    SOPC_UNUSED_ARG(ppTrustedCerts);
1516
    SOPC_UNUSED_ARG(ppTrustedCrl);
1517
    SOPC_UNUSED_ARG(ppIssuerCerts);
1518
    SOPC_UNUSED_ARG(ppIssuerCrl);
1519
    return SOPC_STATUS_NOT_SUPPORTED;
1520
#else
1521
0
    if (NULL == pPKI || NULL == ppTrustedCerts || NULL == ppTrustedCrl || NULL == ppIssuerCerts || NULL == ppIssuerCrl)
1522
0
    {
1523
0
        return SOPC_STATUS_INVALID_PARAMETERS;
1524
0
    }
1525
1526
0
    SOPC_ReturnStatus status = SOPC_STATUS_OK;
1527
0
    SOPC_ReturnStatus mutStatus = SOPC_Mutex_Lock(&pPKI->mutex);
1528
0
    SOPC_ASSERT(SOPC_STATUS_OK == mutStatus);
1529
1530
0
    SOPC_CertificateList* pTrustedCerts = *ppTrustedCerts;
1531
0
    SOPC_CRLList* pTrustedCrl = *ppTrustedCrl;
1532
0
    SOPC_CertificateList* pIssuerCerts = *ppIssuerCerts;
1533
0
    SOPC_CRLList* pIssuerCrl = *ppIssuerCrl;
1534
1535
0
    status = sopc_pki_merge_certificates(pPKI->pTrustedRoots, pPKI->pTrustedCerts, &pTrustedCerts);
1536
0
    if (SOPC_STATUS_OK == status && NULL != pPKI->pTrustedCrl)
1537
0
    {
1538
0
        status = SOPC_KeyManager_CRL_Copy(pPKI->pTrustedCrl, &pTrustedCrl);
1539
0
    }
1540
0
    if (SOPC_STATUS_OK == status)
1541
0
    {
1542
0
        status = sopc_pki_merge_certificates(pPKI->pIssuerRoots, pPKI->pIssuerCerts, &pIssuerCerts);
1543
0
    }
1544
0
    if (SOPC_STATUS_OK == status && NULL != pPKI->pIssuerCrl)
1545
0
    {
1546
0
        status = SOPC_KeyManager_CRL_Copy(pPKI->pIssuerCrl, &pIssuerCrl);
1547
0
    }
1548
    /* Clear if error */
1549
0
    if (SOPC_STATUS_OK != status)
1550
0
    {
1551
0
        SOPC_KeyManager_Certificate_Free(pTrustedCerts);
1552
0
        SOPC_KeyManager_Certificate_Free(pIssuerCerts);
1553
0
        SOPC_KeyManager_CRL_Free(pTrustedCrl);
1554
0
        SOPC_KeyManager_CRL_Free(pIssuerCrl);
1555
0
        pTrustedCerts = NULL;
1556
0
        pIssuerCerts = NULL;
1557
0
        pTrustedCrl = NULL;
1558
0
        pIssuerCrl = NULL;
1559
0
    }
1560
0
    *ppTrustedCerts = pTrustedCerts;
1561
0
    *ppIssuerCerts = pIssuerCerts;
1562
0
    *ppTrustedCrl = pTrustedCrl;
1563
0
    *ppIssuerCrl = pIssuerCrl;
1564
1565
0
    mutStatus = SOPC_Mutex_Unlock(&pPKI->mutex);
1566
0
    SOPC_ASSERT(SOPC_STATUS_OK == mutStatus);
1567
1568
0
    return status;
1569
0
#endif
1570
0
}
1571
1572
SOPC_ReturnStatus SOPC_PKIProvider_WriteToStore(SOPC_PKIProvider* pPKI, const bool bEraseExistingFiles)
1573
0
{
1574
#ifdef WITH_NO_CRYPTO
1575
    SOPC_UNUSED_ARG(bEraseExistingFiles);
1576
    SOPC_UNUSED_ARG(pPKI);
1577
    return SOPC_STATUS_NOT_SUPPORTED;
1578
#else
1579
0
    if (NULL == pPKI)
1580
0
    {
1581
0
        return SOPC_STATUS_INVALID_PARAMETERS;
1582
0
    }
1583
0
    char* basePath = NULL;
1584
0
    char* path = NULL;
1585
0
    SOPC_ReturnStatus status = SOPC_STATUS_OK;
1586
0
    SOPC_ReturnStatus mutStatus = SOPC_Mutex_Lock(&pPKI->mutex);
1587
0
    SOPC_ASSERT(SOPC_STATUS_OK == mutStatus);
1588
1589
    /* The case of the PKI is built from buffer (there is no store) */
1590
0
    if (NULL == pPKI->directoryStorePath)
1591
0
    {
1592
0
        status = SOPC_STATUS_INVALID_STATE;
1593
0
    }
1594
1595
0
    if (SOPC_STATUS_OK == status)
1596
0
    {
1597
0
        status = may_create_pki_folder(pPKI->directoryStorePath, STR_TRUSTLIST_NAME, &basePath);
1598
0
    }
1599
0
    if (SOPC_STATUS_OK == status)
1600
0
    {
1601
0
        status = may_create_pki_folder(basePath, STR_TRUSTED, &path);
1602
0
    }
1603
0
    if (SOPC_STATUS_OK == status)
1604
0
    {
1605
0
        SOPC_Free(path);
1606
0
        status = may_create_pki_folder(basePath, STR_TRUSTED_CERTS, &path);
1607
0
    }
1608
0
    if (SOPC_STATUS_OK == status)
1609
0
    {
1610
        // Note: might use pPKI->pAllTrusted instead which is equivalent to the merged list
1611
0
        status = write_cert_to_der_files(pPKI->pTrustedRoots, pPKI->pTrustedCerts, path, bEraseExistingFiles);
1612
0
    }
1613
0
    if (SOPC_STATUS_OK == status)
1614
0
    {
1615
0
        SOPC_Free(path);
1616
0
        status = may_create_pki_folder(basePath, STR_TRUSTED_CRL, &path);
1617
0
    }
1618
0
    if (SOPC_STATUS_OK == status)
1619
0
    {
1620
0
        status = write_crl_to_der_files(pPKI->pTrustedCrl, path, bEraseExistingFiles);
1621
0
    }
1622
0
    if (SOPC_STATUS_OK == status)
1623
0
    {
1624
0
        SOPC_Free(path);
1625
0
        status = may_create_pki_folder(basePath, STR_ISSUERS, &path);
1626
0
    }
1627
0
    if (SOPC_STATUS_OK == status)
1628
0
    {
1629
0
        SOPC_Free(path);
1630
0
        status = may_create_pki_folder(basePath, STR_ISSUERS_CERTS, &path);
1631
0
    }
1632
0
    if (SOPC_STATUS_OK == status)
1633
0
    {
1634
0
        status = write_cert_to_der_files(pPKI->pIssuerRoots, pPKI->pIssuerCerts, path, bEraseExistingFiles);
1635
0
    }
1636
0
    if (SOPC_STATUS_OK == status)
1637
0
    {
1638
0
        SOPC_Free(path);
1639
0
        status = may_create_pki_folder(basePath, STR_ISSUERS_CRL, &path);
1640
0
    }
1641
0
    if (SOPC_STATUS_OK == status)
1642
0
    {
1643
0
        status = write_crl_to_der_files(pPKI->pIssuerCrl, path, bEraseExistingFiles);
1644
0
    }
1645
1646
0
    SOPC_Free(basePath);
1647
0
    SOPC_Free(path);
1648
1649
0
    mutStatus = SOPC_Mutex_Unlock(&pPKI->mutex);
1650
0
    SOPC_ASSERT(SOPC_STATUS_OK == mutStatus);
1651
1652
0
    return status;
1653
0
#endif
1654
0
}
1655
1656
SOPC_ReturnStatus SOPC_PKIProvider_CopyRejectedList(SOPC_PKIProvider* pPKI, SOPC_CertificateList** ppCert)
1657
0
{
1658
#ifdef WITH_NO_CRYPTO
1659
    SOPC_UNUSED_ARG(ppCert);
1660
    SOPC_UNUSED_ARG(pPKI);
1661
    return SOPC_STATUS_NOT_SUPPORTED;
1662
#else
1663
0
    if (NULL == pPKI || NULL == ppCert)
1664
0
    {
1665
0
        return SOPC_STATUS_INVALID_PARAMETERS;
1666
0
    }
1667
1668
0
    SOPC_CertificateList* pRejected = NULL;
1669
0
    SOPC_ReturnStatus status = SOPC_STATUS_OK;
1670
0
    SOPC_ReturnStatus mutStatus = SOPC_Mutex_Lock(&pPKI->mutex);
1671
0
    SOPC_ASSERT(SOPC_STATUS_OK == mutStatus);
1672
1673
0
    if (NULL != pPKI->pRejectedList)
1674
0
    {
1675
0
        status = SOPC_KeyManager_Certificate_Copy(pPKI->pRejectedList, &pRejected);
1676
0
    }
1677
    /* Clear */
1678
0
    if (SOPC_STATUS_OK != status)
1679
0
    {
1680
0
        SOPC_KeyManager_Certificate_Free(pRejected);
1681
0
        pRejected = NULL;
1682
0
    }
1683
0
    *ppCert = pRejected;
1684
1685
0
    mutStatus = SOPC_Mutex_Unlock(&pPKI->mutex);
1686
0
    SOPC_ASSERT(SOPC_STATUS_OK == mutStatus);
1687
1688
0
    return status;
1689
0
#endif
1690
0
}
1691
1692
SOPC_ReturnStatus SOPC_PKIProvider_WriteRejectedCertToStore(SOPC_PKIProvider* pPKI)
1693
0
{
1694
#ifdef WITH_NO_CRYPTO
1695
    SOPC_UNUSED_ARG(pPKI);
1696
    return SOPC_STATUS_NOT_SUPPORTED;
1697
#else
1698
0
    if (NULL == pPKI)
1699
0
    {
1700
0
        return SOPC_STATUS_INVALID_PARAMETERS;
1701
0
    }
1702
0
    char* path = NULL;
1703
0
    SOPC_ReturnStatus status = SOPC_STATUS_OK;
1704
0
    SOPC_ReturnStatus mutStatus = SOPC_Mutex_Lock(&pPKI->mutex);
1705
0
    SOPC_ASSERT(SOPC_STATUS_OK == mutStatus);
1706
1707
    /* The case of the PKI is built from buffer (there is no store) */
1708
0
    if (NULL == pPKI->directoryStorePath)
1709
0
    {
1710
0
        status = SOPC_STATUS_INVALID_STATE;
1711
0
    }
1712
0
    if (SOPC_STATUS_OK == status)
1713
0
    {
1714
0
        status = may_create_pki_folder(pPKI->directoryStorePath, STR_REJECTED, &path);
1715
0
        if (SOPC_STATUS_OK == status)
1716
0
        {
1717
0
            status = remove_files(path);
1718
0
        }
1719
0
    }
1720
0
    if (SOPC_STATUS_OK == status && NULL != pPKI->pRejectedList)
1721
0
    {
1722
0
        status = SOPC_KeyManager_Certificate_ToDER_Files(pPKI->pRejectedList, path);
1723
0
    }
1724
0
    SOPC_Free(path);
1725
1726
0
    mutStatus = SOPC_Mutex_Unlock(&pPKI->mutex);
1727
0
    SOPC_ASSERT(SOPC_STATUS_OK == mutStatus);
1728
1729
0
    return status;
1730
0
#endif
1731
0
}
1732
1733
SOPC_ReturnStatus SOPC_PKIProvider_UpdateFromList(SOPC_PKIProvider* pPKI,
1734
                                                  const char* securityPolicyUri,
1735
                                                  SOPC_CertificateList* pTrustedCerts,
1736
                                                  SOPC_CRLList* pTrustedCrl,
1737
                                                  SOPC_CertificateList* pIssuerCerts,
1738
                                                  SOPC_CRLList* pIssuerCrl,
1739
                                                  const bool bIncludeExistingList)
1740
0
{
1741
#ifdef WITH_NO_CRYPTO
1742
    SOPC_UNUSED_ARG(pPKI);
1743
    SOPC_UNUSED_ARG(securityPolicyUri);
1744
    SOPC_UNUSED_ARG(pTrustedCerts);
1745
    SOPC_UNUSED_ARG(pTrustedCrl);
1746
    SOPC_UNUSED_ARG(pIssuerCerts);
1747
    SOPC_UNUSED_ARG(pIssuerCrl);
1748
    SOPC_UNUSED_ARG(bIncludeExistingList);
1749
    return SOPC_STATUS_NOT_SUPPORTED;
1750
#else
1751
    /* Check parameters */
1752
0
    if (NULL == pPKI)
1753
0
    {
1754
0
        return SOPC_STATUS_INVALID_PARAMETERS;
1755
0
    }
1756
0
    if (NULL == pPKI->pUpdateCb)
1757
0
    {
1758
0
        return SOPC_STATUS_INVALID_STATE;
1759
0
    }
1760
1761
0
    SOPC_PKIProvider* pTmpPKI = NULL;
1762
0
    SOPC_ReturnStatus status = SOPC_STATUS_OK;
1763
0
    SOPC_ReturnStatus mutStatus = SOPC_Mutex_Lock(&pPKI->mutex);
1764
0
    SOPC_ASSERT(SOPC_STATUS_OK == mutStatus);
1765
1766
    /* Check the number of certificates plus CRLs */
1767
0
    status =
1768
0
        sopc_pki_check_list_length(pPKI, pTrustedCerts, pTrustedCrl, pIssuerCerts, pIssuerCrl, bIncludeExistingList);
1769
1770
    /* Handle that the security level of the update isn't higher than the
1771
    security level of the secure channel. (§7.3.4 part 2 v1.05) */
1772
0
    if (SOPC_STATUS_OK == status)
1773
0
    {
1774
0
        status = sopc_pki_check_security_level_of_the_update(pTrustedCerts, pTrustedCrl, pIssuerCerts, pIssuerCrl,
1775
0
                                                             securityPolicyUri);
1776
0
    }
1777
1778
0
    if (SOPC_STATUS_OK == status)
1779
0
    {
1780
        /* Includes the existing TrustList plus any updates */
1781
0
        if (bIncludeExistingList && !pPKI->isPermissive)
1782
0
        {
1783
0
            SOPC_CertificateList* tmp_pTrustedCerts = NULL; /* trusted intermediate CA + trusted certificates */
1784
0
            SOPC_CertificateList* tmp_pTrustedCertsTmp = NULL;
1785
0
            SOPC_CRLList* tmp_pTrustedCrl = NULL;          /* CRLs of trusted intermediate CA and trusted root CA */
1786
0
            SOPC_CertificateList* tmp_pIssuerCerts = NULL; /* issuer intermediate CA + issuer root CA */
1787
0
            SOPC_CertificateList* tmp_pIssuerCertsTmp = NULL;
1788
0
            SOPC_CRLList* tmp_pIssuerCrl = NULL; /* CRLs of issuer intermediate CA and issuer root CA */
1789
1790
            /* tmp_pTrustedCerts = pTrustedCerts + pPKI->pTrustedCerts + pPKI->pTrustedRoot */
1791
0
            status = sopc_pki_merge_certificates(pPKI->pTrustedCerts, pTrustedCerts, &tmp_pTrustedCertsTmp);
1792
0
            if (SOPC_STATUS_OK == status)
1793
0
            {
1794
0
                status = sopc_pki_merge_certificates(pPKI->pTrustedRoots, tmp_pTrustedCertsTmp, &tmp_pTrustedCerts);
1795
0
            }
1796
            /* tmp_pTrustedCrl = pTrustedCrl + pPKI->pTrustedCrl */
1797
0
            if (SOPC_STATUS_OK == status)
1798
0
            {
1799
0
                status = sopc_pki_merge_crls(pPKI->pTrustedCrl, pTrustedCrl, &tmp_pTrustedCrl);
1800
0
            }
1801
            /* tmp_pIssuerCerts = pIssuerCerts + pPKI->pIssuerCerts + pPKI->pIssuerRoot */
1802
0
            if (SOPC_STATUS_OK == status)
1803
0
            {
1804
0
                status = sopc_pki_merge_certificates(pPKI->pIssuerCerts, pIssuerCerts, &tmp_pIssuerCertsTmp);
1805
0
            }
1806
0
            if (SOPC_STATUS_OK == status)
1807
0
            {
1808
0
                status = sopc_pki_merge_certificates(pPKI->pIssuerRoots, tmp_pIssuerCertsTmp, &tmp_pIssuerCerts);
1809
0
            }
1810
            /* tmp_pIssuerCrl = pIssuerCrl + pPKI->pIssuerCrl */
1811
0
            if (SOPC_STATUS_OK == status)
1812
0
            {
1813
0
                status = sopc_pki_merge_crls(pPKI->pIssuerCrl, pIssuerCrl, &tmp_pIssuerCrl);
1814
0
            }
1815
            /* Create a new tmp PKI */
1816
0
            if (SOPC_STATUS_OK == status)
1817
0
            {
1818
0
                status = SOPC_PKIProvider_CreateFromList(tmp_pTrustedCerts, tmp_pTrustedCrl, tmp_pIssuerCerts,
1819
0
                                                         tmp_pIssuerCrl, &pTmpPKI);
1820
0
            }
1821
1822
0
            SOPC_KeyManager_Certificate_Free(tmp_pTrustedCerts);
1823
0
            SOPC_KeyManager_Certificate_Free(tmp_pTrustedCertsTmp);
1824
0
            SOPC_KeyManager_Certificate_Free(tmp_pIssuerCerts);
1825
0
            SOPC_KeyManager_Certificate_Free(tmp_pIssuerCertsTmp);
1826
0
            SOPC_KeyManager_CRL_Free(tmp_pTrustedCrl);
1827
0
            SOPC_KeyManager_CRL_Free(tmp_pIssuerCrl);
1828
0
        }
1829
0
        else
1830
0
        {
1831
            /* Create a new tmp PKI without the existing TrustList */
1832
0
            status = SOPC_PKIProvider_CreateFromList(pTrustedCerts, pTrustedCrl, pIssuerCerts, pIssuerCrl, &pTmpPKI);
1833
0
        }
1834
0
    }
1835
    /* Copy the rejected list before exchange the data */
1836
0
    if (SOPC_STATUS_OK == status && NULL != pPKI->pRejectedList)
1837
0
    {
1838
0
        status = SOPC_KeyManager_Certificate_Copy(pPKI->pRejectedList, &pTmpPKI->pRejectedList);
1839
0
    }
1840
    /* Copy the directory store path before exchange the data */
1841
0
    if (SOPC_STATUS_OK == status && NULL != pPKI->directoryStorePath)
1842
0
    {
1843
0
        pTmpPKI->directoryStorePath = SOPC_strdup(pPKI->directoryStorePath);
1844
0
        if (NULL == pTmpPKI->directoryStorePath)
1845
0
        {
1846
0
            status = SOPC_STATUS_OUT_OF_MEMORY;
1847
0
        }
1848
0
    }
1849
1850
    /* Copy callback pointer and param before exchange the data */
1851
0
    if (SOPC_STATUS_OK == status)
1852
0
    {
1853
0
        pTmpPKI->pUpdateCb = pPKI->pUpdateCb;
1854
0
        pTmpPKI->updateCbParam = pPKI->updateCbParam;
1855
0
    }
1856
1857
    // Exchange the internal data between tmpPKI and PKI, clear previous data and free tmpPKI structure
1858
    // Note: mutex is kept since PKI should already be in use
1859
0
    if (SOPC_STATUS_OK == status)
1860
0
    {
1861
0
        sopc_internal_replace_pki_and_clear(pPKI, &pTmpPKI);
1862
0
    }
1863
1864
    // In case of failure we need to clear and free the temporary PKI
1865
0
    if (NULL != pTmpPKI)
1866
0
    {
1867
0
        sopc_pki_clear(pTmpPKI);
1868
0
        SOPC_Free(pTmpPKI);
1869
0
        pTmpPKI = NULL;
1870
0
    }
1871
1872
0
    if (SOPC_STATUS_OK == status)
1873
0
    {
1874
0
        pPKI->pUpdateCb(pPKI->updateCbParam);
1875
0
    }
1876
1877
    // Unlock PKI prior to possibly clearing it
1878
0
    mutStatus = SOPC_Mutex_Unlock(&pPKI->mutex);
1879
0
    SOPC_ASSERT(SOPC_STATUS_OK == mutStatus);
1880
1881
0
    return status;
1882
0
#endif
1883
0
}
1884
1885
SOPC_ReturnStatus SOPC_PKIProvider_RemoveCertificate(SOPC_PKIProvider* pPKI,
1886
                                                     const char* pThumbprint,
1887
                                                     const bool bIsTrusted,
1888
                                                     bool* pIsRemoved,
1889
                                                     bool* pIsIssuer)
1890
0
{
1891
#ifdef WITH_NO_CRYPTO
1892
    SOPC_UNUSED_ARG(pPKI);
1893
    SOPC_UNUSED_ARG(pThumbprint);
1894
    SOPC_UNUSED_ARG(bIsTrusted);
1895
    SOPC_UNUSED_ARG(pIsRemoved);
1896
    SOPC_UNUSED_ARG(pIsIssuer);
1897
    return SOPC_STATUS_NOT_SUPPORTED;
1898
#else
1899
    /* Initialized the value to return */
1900
0
    *pIsRemoved = false;
1901
0
    *pIsIssuer = false;
1902
0
    if (NULL == pPKI || NULL == pThumbprint)
1903
0
    {
1904
0
        return SOPC_STATUS_INVALID_PARAMETERS;
1905
0
    }
1906
0
    if (NULL == pPKI->pUpdateCb)
1907
0
    {
1908
0
        return SOPC_STATUS_INVALID_STATE;
1909
0
    }
1910
1911
0
    size_t lenThumbprint = strlen(pThumbprint);
1912
0
    if (HEX_THUMBPRINT_SIZE != lenThumbprint)
1913
0
    {
1914
0
        return SOPC_STATUS_INVALID_PARAMETERS;
1915
0
    }
1916
1917
0
    bool bRootIsRemoved = false;
1918
0
    bool bCertIsRemoved = false;
1919
0
    bool bCertIsCA = false;
1920
0
    bool bRootIsCA = false;
1921
1922
0
    bool bIsIssuer = false;
1923
0
    bool bIsRemoved = false;
1924
0
    SOPC_ReturnStatus status = SOPC_STATUS_OK;
1925
1926
0
    SOPC_ReturnStatus mutStatus = SOPC_Mutex_Lock(&pPKI->mutex);
1927
0
    SOPC_ASSERT(SOPC_STATUS_OK == mutStatus);
1928
1929
    /* Remove from trusted certificates */
1930
0
    if (bIsTrusted)
1931
0
    {
1932
0
        if (NULL != pPKI->pTrustedCerts)
1933
0
        {
1934
0
            status = sopc_pki_remove_cert_by_thumbprint(&pPKI->pTrustedCerts, &pPKI->pTrustedCrl, pThumbprint,
1935
0
                                                        "trusted list", &bCertIsRemoved, &bCertIsCA);
1936
0
        }
1937
0
        if (NULL != pPKI->pTrustedRoots && SOPC_STATUS_OK == status)
1938
0
        {
1939
0
            status = sopc_pki_remove_cert_by_thumbprint(&pPKI->pTrustedRoots, &pPKI->pTrustedCrl, pThumbprint,
1940
0
                                                        "trusted root list", &bRootIsRemoved, &bRootIsCA);
1941
0
            SOPC_ASSERT(SOPC_STATUS_OK != status || bRootIsCA == bRootIsRemoved);
1942
0
        }
1943
0
        if (NULL != pPKI->pAllTrusted && SOPC_STATUS_OK == status)
1944
0
        {
1945
0
            bool bAllTrustedRemoved = false;
1946
0
            bool bAllTrustedIsCA = false;
1947
0
            status = sopc_pki_remove_cert_by_thumbprint(&pPKI->pAllTrusted, &pPKI->pTrustedCrl, pThumbprint, NULL,
1948
0
                                                        &bAllTrustedRemoved, &bAllTrustedIsCA);
1949
0
            SOPC_ASSERT(SOPC_STATUS_OK != status || (bAllTrustedRemoved == (bRootIsRemoved || bCertIsRemoved) &&
1950
0
                                                     (bAllTrustedIsCA == (bCertIsCA || bRootIsCA))));
1951
0
        }
1952
0
    }
1953
0
    else
1954
0
    {
1955
        /* Remove from issuer certificates */
1956
0
        if (NULL != pPKI->pIssuerCerts)
1957
0
        {
1958
0
            status = sopc_pki_remove_cert_by_thumbprint(&pPKI->pIssuerCerts, &pPKI->pIssuerCrl, pThumbprint,
1959
0
                                                        "issuer list", &bCertIsRemoved, &bCertIsCA);
1960
0
            SOPC_ASSERT(SOPC_STATUS_OK != status || bCertIsCA == bCertIsRemoved);
1961
0
        }
1962
0
        if (NULL != pPKI->pIssuerRoots && SOPC_STATUS_OK == status)
1963
0
        {
1964
0
            status = sopc_pki_remove_cert_by_thumbprint(&pPKI->pIssuerRoots, &pPKI->pIssuerCrl, pThumbprint,
1965
0
                                                        "issuer root list", &bRootIsRemoved, &bRootIsCA);
1966
0
            SOPC_ASSERT(SOPC_STATUS_OK != status || bRootIsCA == bRootIsRemoved);
1967
0
        }
1968
0
    }
1969
0
    if (SOPC_STATUS_OK == status)
1970
0
    {
1971
0
        if (bCertIsRemoved || bRootIsRemoved)
1972
0
        {
1973
0
            bIsIssuer = bCertIsCA || bRootIsCA;
1974
0
            bIsRemoved = true;
1975
0
        }
1976
0
        else
1977
0
        {
1978
0
            SOPC_Logger_TraceWarning(SOPC_LOG_MODULE_COMMON,
1979
0
                                     "> PKI remove: certificate thumbprint <%s> has not been found", pThumbprint);
1980
0
        }
1981
0
    }
1982
0
    if (SOPC_STATUS_OK == status && bIsRemoved)
1983
0
    {
1984
0
        bool bAllCertIsRemoved = false;
1985
0
        bool bAllRootIsRemoved = false;
1986
0
        bool bAllCertIsCA = false;
1987
0
        bool bAllRootIsCA = false;
1988
        /* Remove from all list */
1989
0
        if (NULL != pPKI->pAllCerts)
1990
0
        {
1991
0
            status = sopc_pki_remove_cert_by_thumbprint(&pPKI->pAllCerts, &pPKI->pAllCrl, pThumbprint, NULL,
1992
0
                                                        &bAllCertIsRemoved, &bAllCertIsCA);
1993
0
        }
1994
0
        if (NULL != pPKI->pAllRoots && SOPC_STATUS_OK == status)
1995
0
        {
1996
0
            status = sopc_pki_remove_cert_by_thumbprint(&pPKI->pAllRoots, &pPKI->pAllCrl, pThumbprint, NULL,
1997
0
                                                        &bAllRootIsRemoved, &bAllRootIsCA);
1998
0
            SOPC_ASSERT(SOPC_STATUS_OK != status || bAllRootIsCA == bAllRootIsRemoved);
1999
0
        }
2000
0
        SOPC_ASSERT(SOPC_STATUS_OK != status || (bCertIsRemoved == bAllCertIsRemoved && bCertIsCA == bAllCertIsCA));
2001
0
        SOPC_ASSERT(SOPC_STATUS_OK != status || (bRootIsRemoved == bAllRootIsRemoved && bRootIsCA == bAllRootIsCA));
2002
0
    }
2003
2004
0
    *pIsIssuer = bIsIssuer;
2005
0
    *pIsRemoved = bIsRemoved;
2006
2007
0
    if (SOPC_STATUS_OK == status && bIsRemoved)
2008
0
    {
2009
0
        pPKI->pUpdateCb(pPKI->updateCbParam);
2010
0
    }
2011
2012
0
    mutStatus = SOPC_Mutex_Unlock(&pPKI->mutex);
2013
0
    SOPC_ASSERT(SOPC_STATUS_OK == mutStatus);
2014
2015
0
    return status;
2016
0
#endif
2017
0
}
2018
2019
SOPC_ReturnStatus SOPC_PKIProvider_CreateFromStore(const char* directoryStorePath, SOPC_PKIProvider** ppPKI)
2020
0
{
2021
#ifdef WITH_NO_CRYPTO
2022
    SOPC_UNUSED_ARG(ppPKI);
2023
    SOPC_UNUSED_ARG(directoryStorePath);
2024
    return SOPC_STATUS_NOT_SUPPORTED;
2025
#else
2026
0
    if (NULL == directoryStorePath || NULL == ppPKI)
2027
0
    {
2028
0
        return SOPC_STATUS_INVALID_PARAMETERS;
2029
0
    }
2030
2031
0
    SOPC_ReturnStatus status = pki_create_from_store(directoryStorePath, false, ppPKI);
2032
0
    return status;
2033
0
#endif
2034
0
}
2035
2036
SOPC_ReturnStatus SOPC_PKIProvider_ValidateCertificate(SOPC_PKIProvider* pPKI,
2037
                                                       const SOPC_CertificateList* pToValidate,
2038
                                                       const SOPC_PKI_Profile* pProfile,
2039
                                                       uint32_t* error,
2040
                                                       SOPC_PKI_Cert_Failure_Context* context)
2041
0
{
2042
#ifdef WITH_NO_CRYPTO
2043
    SOPC_UNUSED_ARG(pPKI);
2044
    SOPC_UNUSED_ARG(pToValidate);
2045
    SOPC_UNUSED_ARG(pProfile);
2046
    SOPC_UNUSED_ARG(error);
2047
    SOPC_UNUSED_ARG(context);
2048
    return SOPC_STATUS_NOT_SUPPORTED;
2049
#else
2050
0
    if (NULL == pPKI)
2051
0
    {
2052
0
        return SOPC_STATUS_INVALID_PARAMETERS;
2053
0
    }
2054
0
    SOPC_ReturnStatus mutStatus = SOPC_Mutex_Lock(&pPKI->mutex);
2055
0
    SOPC_ASSERT(SOPC_STATUS_OK == mutStatus);
2056
0
    SOPC_ReturnStatus status = SOPC_STATUS_INVALID_PARAMETERS;
2057
0
    if (NULL != pPKI->pFnValidateCert)
2058
0
    {
2059
0
        status = pPKI->pFnValidateCert(pPKI, pToValidate, pProfile, error, context);
2060
0
    }
2061
0
    mutStatus = SOPC_Mutex_Unlock(&pPKI->mutex);
2062
0
    SOPC_ASSERT(SOPC_STATUS_OK == mutStatus);
2063
0
    return status;
2064
0
#endif
2065
0
}
2066
2067
SOPC_ReturnStatus SOPC_PKIProvider_CreateFromList(SOPC_CertificateList* pTrustedCerts,
2068
                                                  SOPC_CRLList* pTrustedCrl,
2069
                                                  SOPC_CertificateList* pIssuerCerts,
2070
                                                  SOPC_CRLList* pIssuerCrl,
2071
                                                  SOPC_PKIProvider** ppPKI)
2072
0
{
2073
#ifdef WITH_NO_CRYPTO
2074
    SOPC_UNUSED_ARG(pTrustedCerts);
2075
    SOPC_UNUSED_ARG(pTrustedCrl);
2076
    SOPC_UNUSED_ARG(pIssuerCerts);
2077
    SOPC_UNUSED_ARG(pIssuerCrl);
2078
    SOPC_UNUSED_ARG(ppPKI);
2079
    return SOPC_STATUS_NOT_SUPPORTED;
2080
#else
2081
0
    SOPC_ReturnStatus status = SOPC_STATUS_OK;
2082
0
    SOPC_PKIProvider* pPKI = NULL;
2083
0
    SOPC_CertificateList* tmp_pTrustedRoots = NULL; /* trusted root CA */
2084
0
    SOPC_CertificateList* tmp_pIssuerRoots = NULL;  /* issuer root CA */
2085
0
    SOPC_CertificateList* tmp_pAllRoots = NULL;     /* issuer + trusted roots */
2086
0
    SOPC_CertificateList* tmp_pAllCerts = NULL;     /* issuer + trusted certs */
2087
0
    SOPC_CertificateList* tmp_pAllTrusted = NULL;   /* trusted CAs and certs */
2088
2089
0
    SOPC_CRLList* tmp_pAllCrl = NULL; /* issuer crl + trusted crl  */
2090
2091
0
    SOPC_CertificateList* tmp_pTrustedCerts = NULL; /* trusted intermediate CA + trusted certificates */
2092
0
    SOPC_CRLList* tmp_pTrustedCrl = NULL;           /* CRLs of trusted intermediate CA and trusted root CA */
2093
0
    SOPC_CertificateList* tmp_pIssuerCerts = NULL;  /* issuer intermediate CA + issuer root CA */
2094
0
    SOPC_CRLList* tmp_pIssuerCrl = NULL;            /* CRLs of issuer intermediate CA and issuer root CA */
2095
0
    bool bTrustedCaFound = false;
2096
0
    bool bIssuerCaFound = false;
2097
0
    uint32_t listLength = 0;
2098
2099
0
    if (NULL == ppPKI)
2100
0
    {
2101
0
        return SOPC_STATUS_INVALID_PARAMETERS;
2102
0
    }
2103
2104
    /* Check the number of certificates plus CRLs of the PKI */
2105
0
    status = sopc_pki_get_list_length(pTrustedCerts, pTrustedCrl, pIssuerCerts, pIssuerCrl, &listLength);
2106
0
    if (SOPC_STATUS_OK != status)
2107
0
    {
2108
0
        return status;
2109
0
    }
2110
0
    if (SOPC_PKI_MAX_NB_CERT_AND_CRL < listLength)
2111
0
    {
2112
0
        SOPC_Logger_TraceError(SOPC_LOG_MODULE_COMMON,
2113
0
                               "> PKI creation error: too many (%" PRIu32
2114
0
                               ") certificates and CRLs. The maximum configured is %" PRIu32
2115
0
                               ", please change SOPC_PKI_MAX_NB_CERT_AND_CRL",
2116
0
                               listLength, (uint32_t) SOPC_PKI_MAX_NB_CERT_AND_CRL);
2117
0
        return SOPC_STATUS_INVALID_PARAMETERS;
2118
0
    }
2119
2120
    /*
2121
       - Check that pTrustedCerts is not empty.
2122
       - Check if there are CAs but no CRLs.
2123
       - Check if issuerCerts list is only filled with CA.
2124
       - Check and warn if issuerCerts is not empty but pTrustedCerts is only filed with CA.
2125
         In this case, if there is no root into pTrustedCerts then
2126
         no certificates will be accepted during validation process.
2127
       - Check and warn in case no root defined but trusted certificates defined.
2128
         In this case, only trusted self-signed issued certificates will be accepted.
2129
    */
2130
0
    if (SOPC_STATUS_OK == status)
2131
0
    {
2132
0
        status = sopc_pki_check_lists(pTrustedCerts, pIssuerCerts, pTrustedCrl, pIssuerCrl, &bTrustedCaFound,
2133
0
                                      &bIssuerCaFound);
2134
0
        if (SOPC_STATUS_OK != status)
2135
0
        {
2136
0
            return status;
2137
0
        }
2138
0
    }
2139
2140
    /* Copy the lists */
2141
0
    status = SOPC_KeyManager_Certificate_Copy(pTrustedCerts, &tmp_pTrustedCerts);
2142
0
    if (SOPC_STATUS_OK == status && NULL != pTrustedCrl)
2143
0
    {
2144
0
        status = SOPC_KeyManager_CRL_Copy(pTrustedCrl, &tmp_pTrustedCrl);
2145
0
    }
2146
0
    if (SOPC_STATUS_OK == status && NULL != pIssuerCerts)
2147
0
    {
2148
0
        status = SOPC_KeyManager_Certificate_Copy(pIssuerCerts, &tmp_pIssuerCerts);
2149
0
    }
2150
0
    if (SOPC_STATUS_OK == status && NULL != pIssuerCrl)
2151
0
    {
2152
0
        status = SOPC_KeyManager_CRL_Copy(pIssuerCrl, &tmp_pIssuerCrl);
2153
0
    }
2154
2155
    /* Check the CRL-CA association before creating the PKI. */
2156
0
    bool bTrustedCRL = false;
2157
0
    bool bIssuerCRL = false;
2158
0
    if (SOPC_STATUS_OK == status)
2159
0
    {
2160
0
        if (bTrustedCaFound && NULL != tmp_pTrustedCrl)
2161
0
        {
2162
0
            status = SOPC_KeyManager_CertificateList_CheckCRL(tmp_pTrustedCerts, tmp_pTrustedCrl, &bTrustedCRL);
2163
0
        }
2164
0
        else
2165
0
        {
2166
0
            bTrustedCRL = true;
2167
0
        }
2168
0
    }
2169
0
    if (SOPC_STATUS_OK == status)
2170
0
    {
2171
0
        if (bIssuerCaFound && NULL != tmp_pIssuerCrl)
2172
0
        {
2173
0
            status = SOPC_KeyManager_CertificateList_CheckCRL(tmp_pIssuerCerts, tmp_pIssuerCrl, &bIssuerCRL);
2174
0
        }
2175
0
        else
2176
0
        {
2177
0
            bIssuerCRL = true;
2178
0
        }
2179
0
    }
2180
0
    if (SOPC_STATUS_OK == status && (!bTrustedCRL || !bIssuerCRL))
2181
0
    {
2182
0
        if (!bTrustedCRL)
2183
0
        {
2184
0
            SOPC_Logger_TraceWarning(
2185
0
                SOPC_LOG_MODULE_COMMON,
2186
0
                "> PKI creation warning: Not all certificate authorities in given trusted certificates have at least "
2187
0
                "one certificate revocation list! Certificates issued by these CAs will be refused.");
2188
0
        }
2189
0
        if (!bIssuerCRL)
2190
0
        {
2191
0
            SOPC_Logger_TraceWarning(
2192
0
                SOPC_LOG_MODULE_COMMON,
2193
0
                "> PKI creation warning: Not all certificate authorities in given issuer certificates have at least "
2194
0
                "one certificate revocation list! Certificates issued by these CAs will be refused.");
2195
0
        }
2196
0
    }
2197
    /* Retrieve the root from list */
2198
0
    if (SOPC_STATUS_OK == status)
2199
0
    {
2200
0
        status = SOPC_PKIProviderInternal_SplitRootFromCertList(&tmp_pTrustedCerts, &tmp_pTrustedRoots);
2201
0
    }
2202
0
    if (SOPC_STATUS_OK == status && NULL != tmp_pIssuerCerts)
2203
0
    {
2204
0
        status = SOPC_PKIProviderInternal_SplitRootFromCertList(&tmp_pIssuerCerts, &tmp_pIssuerRoots);
2205
0
    }
2206
    /* Merge trusted and issuer list */
2207
0
    if (SOPC_STATUS_OK == status)
2208
0
    {
2209
0
        status = sopc_pki_merge_certificates(tmp_pIssuerCerts, tmp_pTrustedCerts, &tmp_pAllCerts);
2210
0
    }
2211
0
    if (SOPC_STATUS_OK == status)
2212
0
    {
2213
0
        status = sopc_pki_merge_certificates(tmp_pIssuerRoots, tmp_pTrustedRoots, &tmp_pAllRoots);
2214
0
    }
2215
0
    if (SOPC_STATUS_OK == status)
2216
0
    {
2217
0
        status = sopc_pki_merge_crls(tmp_pIssuerCrl, tmp_pTrustedCrl, &tmp_pAllCrl);
2218
0
    }
2219
0
    if (SOPC_STATUS_OK == status)
2220
0
    {
2221
0
        status = SOPC_KeyManager_Certificate_Copy(pTrustedCerts, &tmp_pAllTrusted);
2222
0
    }
2223
    /* Create the PKI */
2224
0
    if (SOPC_STATUS_OK == status)
2225
0
    {
2226
0
        pPKI = SOPC_Calloc(1, sizeof(SOPC_PKIProvider));
2227
0
        if (NULL == pPKI)
2228
0
        {
2229
0
            status = SOPC_STATUS_OUT_OF_MEMORY;
2230
0
        }
2231
0
    }
2232
2233
0
    if (SOPC_STATUS_OK == status)
2234
0
    {
2235
0
        SOPC_ReturnStatus mutStatus = SOPC_Mutex_Initialization(&pPKI->mutex);
2236
0
        SOPC_ASSERT(SOPC_STATUS_OK == mutStatus);
2237
0
        pPKI->pTrustedRoots = tmp_pTrustedRoots;
2238
0
        pPKI->pTrustedCerts = tmp_pTrustedCerts;
2239
0
        pPKI->pTrustedCrl = tmp_pTrustedCrl;
2240
0
        pPKI->pIssuerRoots = tmp_pIssuerRoots;
2241
0
        pPKI->pIssuerCerts = tmp_pIssuerCerts;
2242
0
        pPKI->pIssuerCrl = tmp_pIssuerCrl;
2243
0
        pPKI->pAllCerts = tmp_pAllCerts;
2244
0
        pPKI->pAllRoots = tmp_pAllRoots;
2245
0
        pPKI->pAllTrusted = tmp_pAllTrusted;
2246
0
        pPKI->pAllCrl = tmp_pAllCrl;
2247
0
        pPKI->pRejectedList = NULL;
2248
0
        pPKI->directoryStorePath = NULL;
2249
0
        pPKI->pFnValidateCert = &SOPC_PKIProviderInternal_ValidateProfileAndCertificate;
2250
0
        pPKI->pUpdateCb = NULL;
2251
0
        pPKI->updateCbParam = 0;
2252
0
        pPKI->isPermissive = false;
2253
0
        *ppPKI = pPKI;
2254
0
    }
2255
0
    else
2256
0
    {
2257
0
        SOPC_KeyManager_Certificate_Free(tmp_pTrustedRoots);
2258
0
        SOPC_KeyManager_Certificate_Free(tmp_pIssuerRoots);
2259
0
        SOPC_KeyManager_Certificate_Free(tmp_pAllRoots);
2260
0
        SOPC_KeyManager_Certificate_Free(tmp_pAllTrusted);
2261
0
        SOPC_KeyManager_Certificate_Free(tmp_pTrustedCerts);
2262
0
        SOPC_KeyManager_Certificate_Free(tmp_pIssuerCerts);
2263
0
        SOPC_KeyManager_Certificate_Free(tmp_pAllCerts);
2264
0
        SOPC_KeyManager_CRL_Free(tmp_pTrustedCrl);
2265
0
        SOPC_KeyManager_CRL_Free(tmp_pIssuerCrl);
2266
0
        SOPC_KeyManager_CRL_Free(tmp_pAllCrl);
2267
0
    }
2268
2269
0
    return status;
2270
0
#endif
2271
0
}