• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * This file is part of the openHiTLS project.
3  *
4  * openHiTLS is licensed under the Mulan PSL v2.
5  * You can use this software according to the terms and conditions of the Mulan PSL v2.
6  * You may obtain a copy of Mulan PSL v2 at:
7  *
8  *     http://license.coscl.org.cn/MulanPSL2
9  *
10  * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
11  * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
12  * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
13  * See the Mulan PSL v2 for more details.
14  */
15 
16 #include <stdint.h>
17 #include "tls_binlog_id.h"
18 #include "bsl_log_internal.h"
19 #include "bsl_log.h"
20 #include "bsl_err_internal.h"
21 #include "bsl_sal.h"
22 #include "bsl_list.h"
23 #include "hitls_error.h"
24 #include "cert_method.h"
25 #include "cert_mgr_ctx.h"
26 
27 
SAL_CERT_ChainNew(void)28 HITLS_CERT_Chain *SAL_CERT_ChainNew(void)
29 {
30     BslList *newChain = BSL_LIST_New(sizeof(HITLS_CERT_X509 *));
31     if (newChain == NULL) {
32         BSL_ERR_PUSH_ERROR(HITLS_MEMALLOC_FAIL);
33         BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15010, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
34             "new cert chain error: out of memory.", 0, 0, 0, 0);
35     }
36     return newChain;
37 }
38 
SAL_CERT_ChainAppend(HITLS_CERT_Chain * chain,HITLS_CERT_X509 * cert)39 int32_t SAL_CERT_ChainAppend(HITLS_CERT_Chain *chain, HITLS_CERT_X509 *cert)
40 {
41     /* add the tail to the end of the certificate chain, corresponding to the top of the stack */
42     int32_t ret = BSL_LIST_AddElement(chain, cert, BSL_LIST_POS_END);
43     if (ret != BSL_SUCCESS) {
44         BSL_ERR_PUSH_ERROR(ret);
45         BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15011, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
46             "append cert to chain error: out of memory.", 0, 0, 0, 0);
47         return HITLS_MEMALLOC_FAIL;
48     }
49 
50     return HITLS_SUCCESS;
51 }
52 
CertChainInnerDestroyCb(void * cert)53 static void CertChainInnerDestroyCb(void *cert)
54 {
55     SAL_CERT_X509Free((HITLS_CERT_X509 *)cert);
56 }
57 
58 /* release the linked list without retaining the head node */
SAL_CERT_ChainFree(HITLS_CERT_Chain * chain)59 void SAL_CERT_ChainFree(HITLS_CERT_Chain *chain)
60 {
61     /* only certificates on the chain are destroyed, chain itself will be not destroyed */
62     BSL_LIST_DeleteAll(chain, CertChainInnerDestroyCb);
63     BSL_SAL_FREE(chain);
64     return;
65 }
66 
67 /* copy the certificate chain */
SAL_CERT_ChainDup(CERT_MgrCtx * mgrCtx,HITLS_CERT_Chain * chain)68 HITLS_CERT_Chain *SAL_CERT_ChainDup(CERT_MgrCtx *mgrCtx, HITLS_CERT_Chain *chain)
69 {
70     int32_t ret;
71     uint32_t listSize = (uint32_t)BSL_LIST_COUNT(chain);
72     HITLS_CERT_X509 *dupCert = NULL;
73     HITLS_CERT_X509 *currCert = NULL;
74 
75     if (BSL_LIST_COUNT(chain) < 0) {
76         BSL_LOG_BINLOG_FIXLEN(BINLOG_ID16070, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
77             "dup cert chain error: list size tainted.", 0, 0, 0, 0);
78         return NULL;
79     }
80 
81     BslList *newChain = SAL_CERT_ChainNew();
82     if (newChain == NULL) {
83         BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15012, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
84             "dup cert chain error: out of memory.", 0, 0, 0, 0);
85         return NULL;
86     }
87 
88     for (uint32_t index = 0u; index < listSize; ++index) {
89         currCert = (HITLS_CERT_X509 *)BSL_LIST_GetIndexNode(index, chain);
90         if (currCert == NULL) {
91             BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15002, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
92                 "dup cert error: currCert NULL.", 0, 0, 0, 0);
93             goto EXIT;
94         }
95         dupCert = SAL_CERT_X509Dup(mgrCtx, currCert);
96         if (dupCert == NULL) {
97             BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15013, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
98                 "dup cert chain error: x509 dup error.", 0, 0, 0, 0);
99             goto EXIT;
100         }
101         ret = SAL_CERT_ChainAppend(newChain, dupCert);
102         if (ret != HITLS_SUCCESS) {
103             BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15014, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
104                 "dup cert chain error: append new cert node error.", 0, 0, 0, 0);
105             SAL_CERT_X509Free(dupCert);
106             goto EXIT;
107         }
108     }
109 
110     return newChain;
111 EXIT:
112     /* free the certificate chain */
113     SAL_CERT_ChainFree(newChain);
114     return NULL;
115 }