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