Coverage Report

Created: 2026-07-16 06:07

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