Coverage Report

Created: 2025-07-13 07:03

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