• 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 "hitls_build.h"
17 #ifdef HITLS_PKI_X509_VFY
18 #include <string.h>
19 #include "securec.h"
20 #include "hitls_pki_x509.h"
21 #include "sal_atomic.h"
22 #include "bsl_err_internal.h"
23 #include "hitls_crl_local.h"
24 #include "hitls_cert_local.h"
25 #include "hitls_x509_local.h"
26 #include "bsl_obj_internal.h"
27 #include "hitls_pki_errno.h"
28 #include "bsl_list.h"
29 #include "bsl_list_internal.h"
30 #include "hitls_x509_verify.h"
31 
32 typedef int32_t (*HITLS_X509_TrvListCallBack)(void *ctx, void *node);
33 typedef int32_t (*HITLS_X509_TrvListWithParentCallBack)(void *ctx, void *node, void *parent);
34 
35 // lists can be cert, ext, and so on.
HITLS_X509_TrvList(BslList * list,HITLS_X509_TrvListCallBack callBack,void * ctx)36 static int32_t HITLS_X509_TrvList(BslList *list, HITLS_X509_TrvListCallBack callBack, void *ctx)
37 {
38     int32_t ret = HITLS_PKI_SUCCESS;
39     void *node = BSL_LIST_GET_FIRST(list);
40     while (node != NULL) {
41         ret = callBack(ctx, node);
42         if (ret != BSL_SUCCESS) {
43             return ret;
44         }
45         node = BSL_LIST_GET_NEXT(list);
46     }
47     return ret;
48 }
49 
50 // lists can be cert, ext, and so on.
HITLS_X509_TrvListWithParent(BslList * list,HITLS_X509_TrvListWithParentCallBack callBack,void * ctx)51 static int32_t HITLS_X509_TrvListWithParent(BslList *list, HITLS_X509_TrvListWithParentCallBack callBack, void *ctx)
52 {
53     int32_t ret = HITLS_PKI_SUCCESS;
54     void *node = BSL_LIST_GET_FIRST(list);
55     void *parentNode = BSL_LIST_GET_NEXT(list);
56     while (node != NULL && parentNode != NULL) {
57         ret = callBack(ctx, node, parentNode);
58         if (ret != BSL_SUCCESS) {
59             return ret;
60         }
61         node = parentNode;
62         parentNode = BSL_LIST_GET_NEXT(list);
63     }
64     return ret;
65 }
66 
67 #define HITLS_X509_MAX_DEPTH 20
68 
HITLS_X509_StoreCtxFree(HITLS_X509_StoreCtx * storeCtx)69 void HITLS_X509_StoreCtxFree(HITLS_X509_StoreCtx *storeCtx)
70 {
71     if (storeCtx == NULL) {
72         return;
73     }
74     int ret;
75     (void)BSL_SAL_AtomicDownReferences(&storeCtx->references, &ret);
76     if (ret > 0) {
77         return;
78     }
79 
80 #ifdef HITLS_CRYPTO_SM2
81     BSL_SAL_FREE(storeCtx->verifyParam.sm2UserId.data);
82 #endif
83     BSL_LIST_FREE(storeCtx->store, (BSL_LIST_PFUNC_FREE)HITLS_X509_CertFree);
84     BSL_LIST_FREE(storeCtx->crl, (BSL_LIST_PFUNC_FREE)HITLS_X509_CrlFree);
85     BSL_SAL_ReferencesFree(&storeCtx->references);
86     BSL_SAL_Free(storeCtx);
87 }
88 
X509_CrlCmp(HITLS_X509_Crl * crlOri,HITLS_X509_Crl * crl)89 static int32_t X509_CrlCmp(HITLS_X509_Crl *crlOri, HITLS_X509_Crl *crl)
90 {
91     if (crlOri == crl) {
92         return 0;
93     }
94     if (HITLS_X509_CmpNameNode(crlOri->tbs.issuerName, crl->tbs.issuerName) != 0) {
95         return 1;
96     }
97     if (crlOri->tbs.tbsRawDataLen != crl->tbs.tbsRawDataLen) {
98         return 1;
99     }
100     return memcmp(crlOri->tbs.tbsRawData, crl->tbs.tbsRawData, crl->tbs.tbsRawDataLen);
101 }
102 
X509_CertCmp(HITLS_X509_Cert * certOri,HITLS_X509_Cert * cert)103 static int32_t X509_CertCmp(HITLS_X509_Cert *certOri, HITLS_X509_Cert *cert)
104 {
105     if (certOri == cert) {
106         return 0;
107     }
108     if (HITLS_X509_CmpNameNode(certOri->tbs.subjectName, cert->tbs.subjectName) != 0) {
109         return 1;
110     }
111     if (certOri->tbs.tbsRawDataLen != cert->tbs.tbsRawDataLen) {
112         return 1;
113     }
114     return memcmp(certOri->tbs.tbsRawData, cert->tbs.tbsRawData, cert->tbs.tbsRawDataLen);
115 }
116 
HITLS_X509_StoreCtxNew(void)117 HITLS_X509_StoreCtx *HITLS_X509_StoreCtxNew(void)
118 {
119     HITLS_X509_StoreCtx *ctx = (HITLS_X509_StoreCtx *)BSL_SAL_Malloc(sizeof(HITLS_X509_StoreCtx));
120     if (ctx == NULL) {
121         BSL_ERR_PUSH_ERROR(BSL_MALLOC_FAIL);
122         return NULL;
123     }
124 
125     (void)memset_s(ctx, sizeof(HITLS_X509_StoreCtx), 0, sizeof(HITLS_X509_StoreCtx));
126     ctx->store = BSL_LIST_New(sizeof(HITLS_X509_Cert *));
127     if (ctx->store == NULL) {
128         BSL_SAL_Free(ctx);
129         BSL_ERR_PUSH_ERROR(BSL_MALLOC_FAIL);
130         return NULL;
131     }
132     ctx->crl = BSL_LIST_New(sizeof(HITLS_X509_Crl *));
133     if (ctx->crl == NULL) {
134         BSL_SAL_FREE(ctx->store);
135         BSL_SAL_Free(ctx);
136         BSL_ERR_PUSH_ERROR(BSL_MALLOC_FAIL);
137         return NULL;
138     }
139 
140     ctx->verifyParam.maxDepth = HITLS_X509_MAX_DEPTH;
141     ctx->verifyParam.securityBits = 128; // 128: The default number of secure bits.
142     BSL_SAL_ReferencesInit(&(ctx->references));
143     return ctx;
144 }
145 
X509_SetMaxDepth(HITLS_X509_StoreCtx * storeCtx,int32_t * val,uint32_t valLen)146 static int32_t X509_SetMaxDepth(HITLS_X509_StoreCtx *storeCtx, int32_t *val, uint32_t valLen)
147 {
148     if (valLen != sizeof(int32_t)) {
149         BSL_ERR_PUSH_ERROR(HITLS_X509_ERR_INVALID_PARAM);
150         return HITLS_X509_ERR_INVALID_PARAM;
151     }
152 
153     int32_t depth = *val;
154     if (depth > HITLS_X509_MAX_DEPTH) {
155         BSL_ERR_PUSH_ERROR(HITLS_X509_ERR_INVALID_PARAM);
156         return HITLS_X509_ERR_INVALID_PARAM;
157     }
158     storeCtx->verifyParam.maxDepth = depth;
159     return HITLS_PKI_SUCCESS;
160 }
161 
X509_SetParamFlag(HITLS_X509_StoreCtx * storeCtx,uint64_t * val,uint32_t valLen)162 static int32_t X509_SetParamFlag(HITLS_X509_StoreCtx *storeCtx, uint64_t *val, uint32_t valLen)
163 {
164     if (valLen != sizeof(uint64_t)) {
165         BSL_ERR_PUSH_ERROR(HITLS_X509_ERR_INVALID_PARAM);
166         return HITLS_X509_ERR_INVALID_PARAM;
167     }
168 
169     storeCtx->verifyParam.flags |= *val;
170     return HITLS_PKI_SUCCESS;
171 }
172 
X509_SetVerifyTime(HITLS_X509_StoreCtx * storeCtx,int64_t * val,uint32_t valLen)173 static int32_t X509_SetVerifyTime(HITLS_X509_StoreCtx *storeCtx, int64_t *val, uint32_t valLen)
174 {
175     if (valLen != sizeof(int64_t)) {
176         BSL_ERR_PUSH_ERROR(HITLS_X509_ERR_INVALID_PARAM);
177         return HITLS_X509_ERR_INVALID_PARAM;
178     }
179 
180     storeCtx->verifyParam.time = *val;
181     storeCtx->verifyParam.flags |= HITLS_X509_VFY_FLAG_TIME;
182     return HITLS_PKI_SUCCESS;
183 }
184 
X509_SetVerifySecurityBits(HITLS_X509_StoreCtx * storeCtx,uint32_t * val,uint32_t valLen)185 static int32_t X509_SetVerifySecurityBits(HITLS_X509_StoreCtx *storeCtx, uint32_t *val, uint32_t valLen)
186 {
187     if (valLen != sizeof(uint32_t)) {
188         BSL_ERR_PUSH_ERROR(HITLS_X509_ERR_INVALID_PARAM);
189         return HITLS_X509_ERR_INVALID_PARAM;
190     }
191 
192     storeCtx->verifyParam.securityBits = *val;
193     storeCtx->verifyParam.flags |= HITLS_X509_VFY_FLAG_SECBITS;
194     return HITLS_PKI_SUCCESS;
195 }
196 
X509_ClearParamFlag(HITLS_X509_StoreCtx * storeCtx,uint64_t * val,uint32_t valLen)197 static int32_t X509_ClearParamFlag(HITLS_X509_StoreCtx *storeCtx, uint64_t *val, uint32_t valLen)
198 {
199     if (valLen != sizeof(uint64_t)) {
200         BSL_ERR_PUSH_ERROR(HITLS_X509_ERR_INVALID_PARAM);
201         return HITLS_X509_ERR_INVALID_PARAM;
202     }
203 
204     storeCtx->verifyParam.flags &= ~(*val);
205     return HITLS_PKI_SUCCESS;
206 }
207 
X509_CheckCert(HITLS_X509_StoreCtx * storeCtx,HITLS_X509_Cert * cert)208 static int32_t X509_CheckCert(HITLS_X509_StoreCtx *storeCtx, HITLS_X509_Cert *cert)
209 {
210     if (!HITLS_X509_CertIsCA(cert)) {
211         BSL_ERR_PUSH_ERROR(HITLS_X509_ERR_CERT_NOT_CA);
212         return HITLS_X509_ERR_CERT_NOT_CA;
213     }
214     HITLS_X509_List *certStore = storeCtx->store;
215     HITLS_X509_Cert *tmp = BSL_LIST_SearchEx(certStore, cert, (BSL_LIST_PFUNC_CMP)X509_CertCmp);
216     if (tmp != NULL) {
217         BSL_ERR_PUSH_ERROR(HITLS_X509_ERR_CERT_EXIST);
218         return HITLS_X509_ERR_CERT_EXIST;
219     }
220 
221     return HITLS_PKI_SUCCESS;
222 }
223 
X509_SetCA(HITLS_X509_StoreCtx * storeCtx,void * val,bool isCopy)224 static int32_t X509_SetCA(HITLS_X509_StoreCtx *storeCtx, void *val, bool isCopy)
225 {
226     int32_t ret = X509_CheckCert(storeCtx, val);
227     if (ret != HITLS_PKI_SUCCESS) {
228         return ret;
229     }
230     if (isCopy) {
231         int ref;
232         ret = HITLS_X509_CertCtrl(val, HITLS_X509_REF_UP, &ref, sizeof(int));
233         if (ret != HITLS_PKI_SUCCESS) {
234             return ret;
235         }
236     }
237 
238     ret = BSL_LIST_AddElement(storeCtx->store, val, BSL_LIST_POS_BEFORE);
239     if (ret != HITLS_PKI_SUCCESS) {
240         if (isCopy) {
241             HITLS_X509_CertFree(val);
242         }
243         BSL_ERR_PUSH_ERROR(ret);
244     }
245     return ret;
246 }
247 
X509_CheckCRL(HITLS_X509_StoreCtx * storeCtx,HITLS_X509_Crl * crl)248 static int32_t X509_CheckCRL(HITLS_X509_StoreCtx *storeCtx, HITLS_X509_Crl *crl)
249 {
250     HITLS_X509_List *crlStore = storeCtx->crl;
251     HITLS_X509_Crl *tmp = BSL_LIST_SearchEx(crlStore, crl, (BSL_LIST_PFUNC_CMP)X509_CrlCmp);
252     if (tmp != NULL) {
253         BSL_ERR_PUSH_ERROR(HITLS_X509_ERR_CRL_EXIST);
254         return HITLS_X509_ERR_CRL_EXIST;
255     }
256 
257     return HITLS_PKI_SUCCESS;
258 }
259 
X509_SetCRL(HITLS_X509_StoreCtx * storeCtx,void * val)260 static int32_t X509_SetCRL(HITLS_X509_StoreCtx *storeCtx, void *val)
261 {
262     int32_t ret = X509_CheckCRL(storeCtx, val);
263     if (ret != HITLS_PKI_SUCCESS) {
264         return ret;
265     }
266     int ref;
267     ret = HITLS_X509_CrlCtrl(val, HITLS_X509_REF_UP, &ref, sizeof(int));
268     if (ret != HITLS_PKI_SUCCESS) {
269         return ret;
270     }
271     ret = BSL_LIST_AddElement(storeCtx->crl, val, BSL_LIST_POS_BEFORE);
272     if (ret != HITLS_PKI_SUCCESS) {
273         HITLS_X509_CrlFree(val);
274         BSL_ERR_PUSH_ERROR(ret);
275     }
276     return ret;
277 }
278 
X509_RefUp(HITLS_X509_StoreCtx * storeCtx,void * val,uint32_t valLen)279 static int32_t X509_RefUp(HITLS_X509_StoreCtx *storeCtx, void *val, uint32_t valLen)
280 {
281     if (valLen != sizeof(int)) {
282         BSL_ERR_PUSH_ERROR(HITLS_X509_ERR_INVALID_PARAM);
283         return HITLS_X509_ERR_INVALID_PARAM;
284     }
285 
286     return BSL_SAL_AtomicUpReferences(&storeCtx->references, val);
287 }
288 
HITLS_X509_StoreCtxCtrl(HITLS_X509_StoreCtx * storeCtx,int32_t cmd,void * val,uint32_t valLen)289 int32_t HITLS_X509_StoreCtxCtrl(HITLS_X509_StoreCtx *storeCtx, int32_t cmd, void *val, uint32_t valLen)
290 {
291     if (storeCtx == NULL || val == NULL) {
292         BSL_ERR_PUSH_ERROR(HITLS_X509_ERR_INVALID_PARAM);
293         return HITLS_X509_ERR_INVALID_PARAM;
294     }
295     switch (cmd) {
296         case HITLS_X509_STORECTX_SET_PARAM_DEPTH:
297             return X509_SetMaxDepth(storeCtx, val, valLen);
298         case HITLS_X509_STORECTX_SET_PARAM_FLAGS:
299             return X509_SetParamFlag(storeCtx, val, valLen);
300         case HITLS_X509_STORECTX_SET_TIME:
301             return X509_SetVerifyTime(storeCtx, val, valLen);
302         case HITLS_X509_STORECTX_SET_SECBITS:
303             return X509_SetVerifySecurityBits(storeCtx, val, valLen);
304         case HITLS_X509_STORECTX_CLR_PARAM_FLAGS:
305             return X509_ClearParamFlag(storeCtx, val, valLen);
306         case HITLS_X509_STORECTX_DEEP_COPY_SET_CA:
307             return X509_SetCA(storeCtx, val, true);
308         case HITLS_X509_STORECTX_SHALLOW_COPY_SET_CA:
309             return X509_SetCA(storeCtx, val, false);
310         case HITLS_X509_STORECTX_SET_CRL:
311             return X509_SetCRL(storeCtx, val);
312         case HITLS_X509_STORECTX_REF_UP:
313             return X509_RefUp(storeCtx, val, valLen);
314 #ifdef HITLS_CRYPTO_SM2
315         case HITLS_X509_STORECTX_SET_VFY_SM2_USERID:
316             return HITLS_X509_SetSm2UserId(&storeCtx->verifyParam.sm2UserId, val, valLen);
317 #endif
318         default:
319             BSL_ERR_PUSH_ERROR(HITLS_X509_ERR_INVALID_PARAM);
320             return HITLS_X509_ERR_INVALID_PARAM;
321     }
322 }
323 
HITLS_X509_CheckTime(HITLS_X509_StoreCtx * storeCtx,HITLS_X509_ValidTime * validTime)324 int32_t HITLS_X509_CheckTime(HITLS_X509_StoreCtx *storeCtx, HITLS_X509_ValidTime *validTime)
325 {
326     int64_t start = 0;
327     int64_t end = 0;
328     if ((storeCtx->verifyParam.flags & HITLS_X509_VFY_FLAG_TIME) == 0) {
329         return HITLS_PKI_SUCCESS;
330     }
331 
332     int32_t ret = BSL_SAL_DateToUtcTimeConvert(&validTime->start, &start);
333     if (ret != BSL_SUCCESS) {
334         BSL_ERR_PUSH_ERROR(ret);
335         return ret;
336     }
337     if (start > storeCtx->verifyParam.time) {
338         BSL_ERR_PUSH_ERROR(HITLS_X509_ERR_TIME_FUTURE);
339         return HITLS_X509_ERR_TIME_FUTURE;
340     }
341 
342     if ((validTime->flag & BSL_TIME_AFTER_SET) == 0) {
343         return HITLS_PKI_SUCCESS;
344     }
345 
346     ret = BSL_SAL_DateToUtcTimeConvert(&validTime->end, &end);
347     if (ret != BSL_SUCCESS) {
348         BSL_ERR_PUSH_ERROR(ret);
349         return ret;
350     }
351     if (end < storeCtx->verifyParam.time) {
352         BSL_ERR_PUSH_ERROR(HITLS_X509_ERR_TIME_EXPIRED);
353         return HITLS_X509_ERR_TIME_EXPIRED;
354     }
355     return HITLS_PKI_SUCCESS;
356 }
357 
X509_AddCertToChain(HITLS_X509_List * chain,HITLS_X509_Cert * cert)358 static int32_t X509_AddCertToChain(HITLS_X509_List *chain, HITLS_X509_Cert *cert)
359 {
360     int ref;
361     int32_t ret = HITLS_X509_CertCtrl(cert, HITLS_X509_REF_UP, &ref, sizeof(int));
362     if (ret != HITLS_PKI_SUCCESS) {
363         return ret;
364     }
365     ret = BSL_LIST_AddElement(chain, cert, BSL_LIST_POS_END);
366     if (ret != HITLS_PKI_SUCCESS) {
367         HITLS_X509_CertFree(cert);
368         BSL_ERR_PUSH_ERROR(ret);
369     }
370     return ret;
371 }
372 
X509_GetIssueFromChain(HITLS_X509_List * certChain,HITLS_X509_Cert * cert,HITLS_X509_Cert ** issue)373 int32_t X509_GetIssueFromChain(HITLS_X509_List *certChain, HITLS_X509_Cert *cert, HITLS_X509_Cert **issue)
374 {
375     int32_t ret;
376     for (HITLS_X509_Cert *tmp = BSL_LIST_GET_FIRST(certChain); tmp != NULL; tmp = BSL_LIST_GET_NEXT(certChain)) {
377         bool res = false;
378         ret = HITLS_X509_CheckIssued(tmp, cert, &res);
379         if (ret != HITLS_PKI_SUCCESS) {
380             return ret;
381         }
382         if (!res) {
383             continue;
384         }
385         *issue = tmp;
386         return HITLS_PKI_SUCCESS;
387     }
388     BSL_ERR_PUSH_ERROR(HITLS_X509_ERR_ISSUE_CERT_NOT_FOUND);
389     return HITLS_X509_ERR_ISSUE_CERT_NOT_FOUND;
390 }
391 
X509_FindIssueCert(HITLS_X509_StoreCtx * storeCtx,HITLS_X509_List * certChain,HITLS_X509_Cert * cert,HITLS_X509_Cert ** issue,bool * issueInTrust)392 int32_t X509_FindIssueCert(HITLS_X509_StoreCtx *storeCtx, HITLS_X509_List *certChain, HITLS_X509_Cert *cert,
393     HITLS_X509_Cert **issue, bool *issueInTrust)
394 {
395     HITLS_X509_List *store = storeCtx->store;
396     int32_t ret = X509_GetIssueFromChain(store, cert, issue);
397     if (ret == HITLS_PKI_SUCCESS) {
398         *issueInTrust = true;
399         return ret;
400     }
401     if (certChain == NULL) {
402         return ret;
403     }
404     ret = X509_GetIssueFromChain(certChain, cert, issue);
405     if (ret != HITLS_PKI_SUCCESS) {
406         return ret;
407     }
408     *issueInTrust = false;
409     return ret;
410 }
411 
X509_BuildChain(HITLS_X509_StoreCtx * storeCtx,HITLS_X509_List * certChain,HITLS_X509_Cert * cert,HITLS_X509_List * chain,HITLS_X509_Cert ** root)412 int32_t X509_BuildChain(HITLS_X509_StoreCtx *storeCtx, HITLS_X509_List *certChain, HITLS_X509_Cert *cert,
413     HITLS_X509_List *chain, HITLS_X509_Cert **root)
414 {
415     HITLS_X509_Cert *cur = cert;
416     int32_t ret;
417     while (cur != NULL) {
418         HITLS_X509_Cert *issue = NULL;
419         bool isTrustCa = false;
420         ret = X509_FindIssueCert(storeCtx, certChain, cur, &issue, &isTrustCa);
421         if (ret != HITLS_PKI_SUCCESS) {
422             return ret;
423         }
424         // depth
425         if (BSL_LIST_COUNT(chain) + 1 > storeCtx->verifyParam.maxDepth) {
426             BSL_ERR_PUSH_ERROR(HITLS_X509_ERR_CHAIN_DEPTH_UP_LIMIT);
427             return HITLS_X509_ERR_CHAIN_DEPTH_UP_LIMIT;
428         }
429         bool selfSigned = false;
430         ret = HITLS_X509_CheckIssued(issue, issue, &selfSigned);
431         if (ret != HITLS_PKI_SUCCESS) {
432             return ret;
433         }
434         if (selfSigned) {
435             if (root != NULL && isTrustCa) {
436                 *root = issue;
437             }
438             break;
439         }
440         ret = X509_AddCertToChain(chain, issue);
441         if (ret != HITLS_PKI_SUCCESS) {
442             return ret;
443         }
444         cur = issue;
445     }
446     return HITLS_PKI_SUCCESS;
447 }
448 
X509_NewCertChain(HITLS_X509_Cert * cert)449 static HITLS_X509_List *X509_NewCertChain(HITLS_X509_Cert *cert)
450 {
451     HITLS_X509_List *tmpChain = BSL_LIST_New(sizeof(HITLS_X509_Cert *));
452     if (tmpChain == NULL) {
453         BSL_ERR_PUSH_ERROR(BSL_MALLOC_FAIL);
454         return NULL;
455     }
456     int32_t ret = X509_AddCertToChain(tmpChain, cert);
457     if (ret != HITLS_PKI_SUCCESS) {
458         BSL_SAL_Free(tmpChain);
459         BSL_ERR_PUSH_ERROR(ret);
460         return NULL;
461     }
462     return tmpChain;
463 }
464 
HITLS_X509_CertChainBuildWithRoot(HITLS_X509_StoreCtx * storeCtx,HITLS_X509_Cert * cert,HITLS_X509_List ** chain)465 static int32_t HITLS_X509_CertChainBuildWithRoot(HITLS_X509_StoreCtx *storeCtx, HITLS_X509_Cert *cert,
466     HITLS_X509_List **chain)
467 {
468     HITLS_X509_List *tmpChain = X509_NewCertChain(cert);
469     if (tmpChain == NULL) {
470         BSL_ERR_PUSH_ERROR(BSL_MALLOC_FAIL);
471         return BSL_MALLOC_FAIL;
472     }
473     HITLS_X509_Cert *root = NULL;
474     int32_t ret = X509_BuildChain(storeCtx, NULL, cert, tmpChain, &root);
475     if (ret != HITLS_PKI_SUCCESS) {
476         BSL_LIST_FREE(tmpChain, (BSL_LIST_PFUNC_FREE)HITLS_X509_CertFree);
477         return ret;
478     }
479     if (root == NULL) {
480         BSL_LIST_FREE(tmpChain, (BSL_LIST_PFUNC_FREE)HITLS_X509_CertFree);
481         return HITLS_X509_ERR_ROOT_CERT_NOT_FOUND;
482     }
483     if (X509_CertCmp(cert, root) != 0) {
484         ret = X509_AddCertToChain(tmpChain, root);
485         if (ret != HITLS_PKI_SUCCESS) {
486             BSL_LIST_FREE(tmpChain, (BSL_LIST_PFUNC_FREE)HITLS_X509_CertFree);
487             return ret;
488         }
489     }
490     *chain = tmpChain;
491     return HITLS_PKI_SUCCESS;
492 }
493 
HITLS_X509_CertChainBuild(HITLS_X509_StoreCtx * storeCtx,bool isWithRoot,HITLS_X509_Cert * cert,HITLS_X509_List ** chain)494 int32_t HITLS_X509_CertChainBuild(HITLS_X509_StoreCtx *storeCtx, bool isWithRoot, HITLS_X509_Cert *cert,
495     HITLS_X509_List **chain)
496 {
497     if (storeCtx == NULL || cert == NULL || chain == NULL) {
498         BSL_ERR_PUSH_ERROR(HITLS_X509_ERR_INVALID_PARAM);
499         return HITLS_X509_ERR_INVALID_PARAM;
500     }
501     if (isWithRoot) {
502         return HITLS_X509_CertChainBuildWithRoot(storeCtx, cert, chain);
503     }
504     HITLS_X509_List *tmpChain = X509_NewCertChain(cert);
505     if (tmpChain == NULL) {
506         BSL_ERR_PUSH_ERROR(BSL_MALLOC_FAIL);
507         return BSL_MALLOC_FAIL;
508     }
509     bool selfSigned = false;
510     int32_t ret = HITLS_X509_CheckIssued(cert, cert, &selfSigned);
511     if (ret != HITLS_PKI_SUCCESS) {
512         BSL_LIST_FREE(tmpChain, (BSL_LIST_PFUNC_FREE)HITLS_X509_CertFree);
513         return ret;
514     }
515     if (selfSigned) {
516         *chain = tmpChain;
517         return HITLS_PKI_SUCCESS;
518     }
519     (void)X509_BuildChain(storeCtx, NULL, cert, tmpChain, NULL);
520     *chain = tmpChain;
521 
522     return HITLS_PKI_SUCCESS;
523 }
524 
HITLS_X509_SecBitsCheck(HITLS_X509_StoreCtx * storeCtx,HITLS_X509_Cert * cert)525 static int32_t HITLS_X509_SecBitsCheck(HITLS_X509_StoreCtx *storeCtx, HITLS_X509_Cert *cert)
526 {
527     uint32_t secBits = CRYPT_EAL_PkeyGetSecurityBits(cert->tbs.ealPubKey);
528     if (secBits < storeCtx->verifyParam.securityBits) {
529         BSL_ERR_PUSH_ERROR(HITLS_X509_ERR_VFY_CHECK_SECBITS);
530         return HITLS_X509_ERR_VFY_CHECK_SECBITS;
531     }
532     return HITLS_PKI_SUCCESS;
533 }
534 
HITLS_X509_CheckVerifyParam(HITLS_X509_StoreCtx * storeCtx,HITLS_X509_List * chain)535 int32_t HITLS_X509_CheckVerifyParam(HITLS_X509_StoreCtx *storeCtx, HITLS_X509_List *chain)
536 {
537     if ((storeCtx->verifyParam.flags & HITLS_X509_VFY_FLAG_SECBITS) != 0) {
538         return HITLS_X509_TrvList(chain, (HITLS_X509_TrvListCallBack)HITLS_X509_SecBitsCheck, storeCtx);
539     }
540     return HITLS_PKI_SUCCESS;
541 }
542 
HITLS_X509_CheckCertExtNode(void * ctx,HITLS_X509_ExtEntry * extNode)543 static int32_t HITLS_X509_CheckCertExtNode(void *ctx, HITLS_X509_ExtEntry *extNode)
544 {
545     (void)ctx;
546     if (extNode->cid != BSL_CID_CE_KEYUSAGE && extNode->cid != BSL_CID_CE_BASICCONSTRAINTS &&
547         extNode->critical == true) {
548         BSL_ERR_PUSH_ERROR(HITLS_X509_ERR_PROCESS_CRITICALEXT);
549         return HITLS_X509_ERR_PROCESS_CRITICALEXT; // not process critical ext
550     }
551     return HITLS_PKI_SUCCESS;
552 }
553 
HITLS_X509_CheckCertExt(void * ctx,HITLS_X509_Cert * cert)554 static int32_t HITLS_X509_CheckCertExt(void *ctx, HITLS_X509_Cert *cert)
555 {
556     (void) ctx;
557     if (cert->tbs.version != 2) { // no ext v1 cert
558         return HITLS_PKI_SUCCESS;
559     }
560     return HITLS_X509_TrvList(cert->tbs.ext.extList,
561         (HITLS_X509_TrvListCallBack)HITLS_X509_CheckCertExtNode, NULL);
562 }
563 
HITLS_X509_VerifyParamAndExt(HITLS_X509_StoreCtx * storeCtx,HITLS_X509_List * chain)564 int32_t HITLS_X509_VerifyParamAndExt(HITLS_X509_StoreCtx *storeCtx, HITLS_X509_List *chain)
565 {
566     int32_t ret = HITLS_X509_CheckVerifyParam(storeCtx, chain);
567     if (ret != HITLS_PKI_SUCCESS) {
568         return ret;
569     }
570     return HITLS_X509_TrvList(chain, (HITLS_X509_TrvListCallBack)HITLS_X509_CheckCertExt, NULL);
571 }
572 
HITLS_X509_CheckCertRevoked(HITLS_X509_Cert * cert,HITLS_X509_CrlEntry * crlEntry)573 int32_t HITLS_X509_CheckCertRevoked(HITLS_X509_Cert *cert, HITLS_X509_CrlEntry *crlEntry)
574 {
575     if (cert->tbs.serialNum.tag == crlEntry->serialNumber.tag &&
576         cert->tbs.serialNum.len == crlEntry->serialNumber.len &&
577         memcmp(cert->tbs.serialNum.buff, crlEntry->serialNumber.buff, crlEntry->serialNumber.len) == 0) {
578         return HITLS_X509_ERR_VFY_CERT_REVOKED;
579     }
580     return HITLS_PKI_SUCCESS;
581 }
582 
X509_StoreCheckSignature(const BSL_Buffer * sm2UserId,const CRYPT_EAL_PkeyCtx * pubKey,uint8_t * rawData,uint32_t rawDataLen,HITLS_X509_Asn1AlgId * alg,BSL_ASN1_BitString * signature)583 static int32_t X509_StoreCheckSignature(const BSL_Buffer *sm2UserId, const CRYPT_EAL_PkeyCtx *pubKey,
584     uint8_t *rawData, uint32_t rawDataLen, HITLS_X509_Asn1AlgId *alg, BSL_ASN1_BitString *signature)
585 {
586 #ifdef HITLS_CRYPTO_SM2
587     bool isHasUserId = true;
588     if (alg->sm2UserId.data == NULL) {
589         alg->sm2UserId = *sm2UserId;
590         isHasUserId = false;
591     }
592 #else
593     (void)sm2UserId;
594 #endif
595     int32_t ret = HITLS_X509_CheckSignature(pubKey, rawData, rawDataLen, alg, signature);
596     if (ret != HITLS_PKI_SUCCESS) {
597         BSL_ERR_PUSH_ERROR(ret);
598         return ret;
599     }
600 #ifdef HITLS_CRYPTO_SM2
601     if (!isHasUserId) {
602         alg->sm2UserId.data = NULL;
603         alg->sm2UserId.dataLen = 0;
604     }
605 #endif
606     return ret;
607 }
608 
HITLS_X509_CheckCertCrl(HITLS_X509_StoreCtx * storeCtx,HITLS_X509_Cert * cert,HITLS_X509_Cert * parent)609 int32_t HITLS_X509_CheckCertCrl(HITLS_X509_StoreCtx *storeCtx, HITLS_X509_Cert *cert, HITLS_X509_Cert *parent)
610 {
611     int32_t ret = HITLS_X509_ERR_CRL_NOT_FOUND;
612     HITLS_X509_Crl *crl = BSL_LIST_GET_FIRST(storeCtx->crl);
613     HITLS_X509_CertExt *certExt = (HITLS_X509_CertExt *)parent->tbs.ext.extData;
614     if ((certExt->extFlags & HITLS_X509_EXT_FLAG_KUSAGE) != 0) {
615         if ((certExt->keyUsage & HITLS_X509_EXT_KU_CRL_SIGN) == 0) {
616             BSL_ERR_PUSH_ERROR(HITLS_X509_ERR_VFY_KU_NO_CRLSIGN);
617             return HITLS_X509_ERR_VFY_KU_NO_CRLSIGN;
618         }
619     }
620     while (crl != NULL) {
621         if (HITLS_X509_CmpNameNode(crl->tbs.issuerName, parent->tbs.subjectName) != 0) {
622             crl = BSL_LIST_GET_NEXT(storeCtx->crl);
623             continue;
624         }
625         if (cert->tbs.version == HITLS_X509_VERSION_3 && crl->tbs.version == 1) {
626             if (HITLS_X509_CheckAki(&parent->tbs.ext, &crl->tbs.crlExt, parent->tbs.issuerName,
627                 &parent->tbs.serialNum) != HITLS_PKI_SUCCESS) {
628                 crl = BSL_LIST_GET_NEXT(storeCtx->crl);
629                 continue;
630             }
631         }
632         if (HITLS_X509_CheckTime(storeCtx, &(crl->tbs.validTime)) != HITLS_PKI_SUCCESS) {
633             crl = BSL_LIST_GET_NEXT(storeCtx->crl);
634             continue;
635         }
636         ret = HITLS_X509_TrvList(crl->tbs.crlExt.extList,
637             (HITLS_X509_TrvListCallBack)HITLS_X509_CheckCertExtNode, NULL);
638         if (ret != HITLS_PKI_SUCCESS) {
639             BSL_ERR_PUSH_ERROR(ret);
640             return ret;
641         }
642 
643 #ifdef HITLS_CRYPTO_SM2
644         ret = X509_StoreCheckSignature(&storeCtx->verifyParam.sm2UserId, parent->tbs.ealPubKey, crl->tbs.tbsRawData,
645             crl->tbs.tbsRawDataLen, &(crl->signAlgId), &(crl->signature));
646 #else
647         ret = X509_StoreCheckSignature(NULL, parent->tbs.ealPubKey, crl->tbs.tbsRawData,
648             crl->tbs.tbsRawDataLen, &(crl->signAlgId), &(crl->signature));
649 #endif
650         if (ret != HITLS_PKI_SUCCESS) {
651             return ret;
652         }
653         ret = HITLS_X509_TrvList(crl->tbs.revokedCerts, (HITLS_X509_TrvListCallBack)HITLS_X509_CheckCertRevoked, cert);
654         if (ret != HITLS_PKI_SUCCESS) {
655             return ret;
656         }
657         crl = BSL_LIST_GET_NEXT(storeCtx->crl);
658     }
659     return ret;
660 }
661 
HITLS_X509_VerifyCrl(HITLS_X509_StoreCtx * storeCtx,HITLS_X509_List * chain)662 int32_t HITLS_X509_VerifyCrl(HITLS_X509_StoreCtx *storeCtx, HITLS_X509_List *chain)
663 {
664     // Only the self-signed certificate, and the CRL is not verified
665     if (BSL_LIST_COUNT(chain) == 1) {
666         return HITLS_PKI_SUCCESS;
667     }
668 
669     if ((storeCtx->verifyParam.flags & HITLS_X509_VFY_FLAG_CRL_ALL) != 0) {
670         // Device certificate check is included
671         return HITLS_X509_TrvListWithParent(chain,
672             (HITLS_X509_TrvListWithParentCallBack)HITLS_X509_CheckCertCrl, storeCtx);
673     }
674 
675     if ((storeCtx->verifyParam.flags & HITLS_X509_VFY_FLAG_CRL_DEV) != 0) {
676         HITLS_X509_Cert *cert = BSL_LIST_GET_FIRST(chain);
677         HITLS_X509_Cert *parent = BSL_LIST_GET_NEXT(chain);
678         return HITLS_X509_CheckCertCrl(storeCtx, cert, parent);
679     }
680 
681     return HITLS_PKI_SUCCESS;
682 }
683 
X509_VerifyChainCert(HITLS_X509_StoreCtx * storeCtx,HITLS_X509_List * chain)684 int32_t X509_VerifyChainCert(HITLS_X509_StoreCtx *storeCtx, HITLS_X509_List *chain)
685 {
686     HITLS_X509_Cert *issue = BSL_LIST_GET_LAST(chain);
687     HITLS_X509_Cert *cur = issue;
688     int32_t ret;
689     while (cur != NULL) {
690         if ((storeCtx->verifyParam.flags & HITLS_X509_VFY_FLAG_TIME) != 0) {
691             ret = HITLS_X509_CheckTime(storeCtx, &cur->tbs.validTime);
692             if (ret != HITLS_PKI_SUCCESS) {
693                 return ret;
694             }
695         }
696 #ifdef HITLS_CRYPTO_SM2
697         ret = X509_StoreCheckSignature(&storeCtx->verifyParam.sm2UserId, issue->tbs.ealPubKey, cur->tbs.tbsRawData,
698             cur->tbs.tbsRawDataLen, &cur->signAlgId, &cur->signature);
699 #else
700         ret = X509_StoreCheckSignature(NULL, issue->tbs.ealPubKey, cur->tbs.tbsRawData,
701             cur->tbs.tbsRawDataLen, &cur->signAlgId, &cur->signature);
702 #endif
703         if (ret != HITLS_PKI_SUCCESS) {
704             return ret;
705         }
706         issue = cur;
707         cur = BSL_LIST_GET_PREV(chain);
708     };
709     return HITLS_PKI_SUCCESS;
710 }
711 
X509_GetVerifyCertChain(HITLS_X509_StoreCtx * storeCtx,HITLS_X509_List * chain,HITLS_X509_List ** comChain)712 static int32_t X509_GetVerifyCertChain(HITLS_X509_StoreCtx *storeCtx, HITLS_X509_List *chain,
713     HITLS_X509_List **comChain)
714 {
715     HITLS_X509_Cert *cert = BSL_LIST_GET_FIRST(chain);
716     if (cert == NULL) {
717         BSL_ERR_PUSH_ERROR(HITLS_X509_ERR_INVALID_PARAM);
718         return HITLS_X509_ERR_INVALID_PARAM;
719     }
720     HITLS_X509_List *tmpChain = X509_NewCertChain(cert);
721     if (tmpChain == NULL) {
722         BSL_ERR_PUSH_ERROR(BSL_MALLOC_FAIL);
723         return BSL_MALLOC_FAIL;
724     }
725     HITLS_X509_Cert *root = NULL;
726     int32_t ret = X509_BuildChain(storeCtx, chain, cert, tmpChain, &root);
727     if (ret != HITLS_PKI_SUCCESS) {
728         BSL_LIST_FREE(tmpChain, (BSL_LIST_PFUNC_FREE)HITLS_X509_CertFree);
729         BSL_ERR_PUSH_ERROR(ret);
730         return ret;
731     }
732     if (root == NULL) {
733         BSL_LIST_FREE(tmpChain, (BSL_LIST_PFUNC_FREE)HITLS_X509_CertFree);
734         BSL_ERR_PUSH_ERROR(HITLS_X509_ERR_ROOT_CERT_NOT_FOUND);
735         return HITLS_X509_ERR_ROOT_CERT_NOT_FOUND;
736     }
737     if (X509_CertCmp(cert, root) != 0) {
738         ret = X509_AddCertToChain(tmpChain, root);
739         if (ret != HITLS_PKI_SUCCESS) {
740             BSL_LIST_FREE(tmpChain, (BSL_LIST_PFUNC_FREE)HITLS_X509_CertFree);
741             return ret;
742         }
743     }
744     *comChain = tmpChain;
745     return HITLS_PKI_SUCCESS;
746 }
747 
HITLS_X509_CertVerify(HITLS_X509_StoreCtx * storeCtx,HITLS_X509_List * chain)748 int32_t HITLS_X509_CertVerify(HITLS_X509_StoreCtx *storeCtx, HITLS_X509_List *chain)
749 {
750     if (storeCtx == NULL || chain == NULL) {
751         BSL_ERR_PUSH_ERROR(HITLS_X509_ERR_INVALID_PARAM);
752         return HITLS_X509_ERR_INVALID_PARAM;
753     }
754     if (BSL_LIST_COUNT(chain) <= 0) {
755         BSL_ERR_PUSH_ERROR(HITLS_X509_ERR_CERT_CHAIN_COUNT_IS0);
756         return HITLS_X509_ERR_CERT_CHAIN_COUNT_IS0;
757     }
758     HITLS_X509_List *tmpChain = NULL;
759     int32_t ret = X509_GetVerifyCertChain(storeCtx, chain, &tmpChain);
760     if (ret != HITLS_PKI_SUCCESS) {
761         return ret;
762     }
763     ret = HITLS_X509_VerifyParamAndExt(storeCtx, tmpChain);
764     if (ret != HITLS_PKI_SUCCESS) {
765         BSL_LIST_FREE(tmpChain, (BSL_LIST_PFUNC_FREE)HITLS_X509_CertFree);
766         return ret;
767     }
768     ret = HITLS_X509_VerifyCrl(storeCtx, tmpChain);
769     if (ret != HITLS_PKI_SUCCESS) {
770         BSL_LIST_FREE(tmpChain, (BSL_LIST_PFUNC_FREE)HITLS_X509_CertFree);
771         return ret;
772     }
773     ret = X509_VerifyChainCert(storeCtx, tmpChain);
774     BSL_LIST_FREE(tmpChain, (BSL_LIST_PFUNC_FREE)HITLS_X509_CertFree);
775     return ret;
776 }
777 
HITLS_X509_ProviderStoreCtxNew(HITLS_PKI_LibCtx * libCtx,const char * attrName)778 HITLS_X509_StoreCtx *HITLS_X509_ProviderStoreCtxNew(HITLS_PKI_LibCtx *libCtx, const char *attrName)
779 {
780     HITLS_X509_StoreCtx *storeCtx = HITLS_X509_StoreCtxNew();
781     if (storeCtx == NULL) {
782         return NULL;
783     }
784     storeCtx->libCtx = libCtx;
785     storeCtx->attrName = attrName;
786     return storeCtx;
787 }
788 #endif // HITLS_PKI_X509_VFY
789