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 }