已关闭
fix(pki): harden X509 verification for certificate version, SAN parsing, and security level integration #1399
Ooohui创建于 5月13日关闭于 5月13日
fix(pki): harden X509 verification for certificate version, SAN parsing, and security level integration #1399
已关闭
Ooohui创建于 5月13日关闭于 5月13日
33 个文件变更+1121-32
Minclude/pki/hitls_pki_errno.h+4-0
@@ -78,6 +78,9 @@ typedef enum {
78 HITLS_X509_ERR_VFY_PATHLEN_EXCEEDED,78 HITLS_X509_ERR_VFY_PATHLEN_EXCEEDED,
79 HITLS_X509_ERR_VFY_PURPOSE_UNMATCH,79 HITLS_X509_ERR_VFY_PURPOSE_UNMATCH,
80 HITLS_X509_ERR_KU_IS_NONE,80 HITLS_X509_ERR_KU_IS_NONE,
81+ HITLS_X509_ERR_VFY_EXTENSIONS_REQUIRE_V3,
82+ HITLS_X509_ERR_VFY_INTERCA_INVALID_VERSION,
83+ HITLS_X509_ERR_VFY_INTERCA_INVALID_BCONS,
81 84 
82 HITLS_X509_ERR_CERT_NOT_CA = 0x04010001,85 HITLS_X509_ERR_CERT_NOT_CA = 0x04010001,
83 HITLS_X509_ERR_CERT_EXIST,86 HITLS_X509_ERR_CERT_EXIST,
@@ -163,6 +166,7 @@ typedef enum {
163 HITLS_X509_ERR_EXT_NO_BCONS,166 HITLS_X509_ERR_EXT_NO_BCONS,
164 HITLS_X509_ERR_EXT_UNKNOWN_ERROR,167 HITLS_X509_ERR_EXT_UNKNOWN_ERROR,
165 HITLS_X509_ERR_SAN_NOT_FOUND,168 HITLS_X509_ERR_SAN_NOT_FOUND,
169+ HITLS_X509_ERR_PARSE_SAN_ITEM,
166 170 
167 HITLS_X509_ERR_CSR_INVALID_PUBKEY = 0x04050001,171 HITLS_X509_ERR_CSR_INVALID_PUBKEY = 0x04050001,
168 HITLS_X509_ERR_CSR_INVALID_SUBJECT_DN,172 HITLS_X509_ERR_CSR_INVALID_SUBJECT_DN,
Mpki/x509_common/src/hitls_x509_ctrl.c+7-3
@@ -299,13 +299,17 @@ int32_t HITLS_X509_SetNameList(BslList **dest, void *val, uint32_t valLen)
299 return HITLS_X509_ERR_INVALID_PARAM;299 return HITLS_X509_ERR_INVALID_PARAM;
300 }300 }
301 BslList *src = (BslList *)val;301 BslList *src = (BslList *)val;
302+ if (src == *dest) {
303+ return HITLS_PKI_SUCCESS;
304+ }
302 305 
303- BSL_LIST_FREE(*dest, (BSL_LIST_PFUNC_FREE)HITLS_X509_FreeNameNode);306+ BslList *tmp = BSL_LIST_Copy(src, (BSL_LIST_PFUNC_DUP)DupNameNode, (BSL_LIST_PFUNC_FREE)HITLS_X509_FreeNameNode);
304- *dest = BSL_LIST_Copy(src, (BSL_LIST_PFUNC_DUP)DupNameNode, (BSL_LIST_PFUNC_FREE)HITLS_X509_FreeNameNode);307+ if (tmp == NULL) {
305- if (*dest == NULL) {
306 BSL_ERR_PUSH_ERROR(HITLS_X509_ERR_SET_NAME_LIST);308 BSL_ERR_PUSH_ERROR(HITLS_X509_ERR_SET_NAME_LIST);
307 return HITLS_X509_ERR_SET_NAME_LIST;309 return HITLS_X509_ERR_SET_NAME_LIST;
308 }310 }
311+ BSL_LIST_FREE(*dest, (BSL_LIST_PFUNC_FREE)HITLS_X509_FreeNameNode);
312+ *dest = tmp;
309 return HITLS_PKI_SUCCESS;313 return HITLS_PKI_SUCCESS;
310}314}
311 315 
Mpki/x509_common/src/hitls_x509_ext.c+8-7
@@ -383,18 +383,19 @@ int32_t HITLS_X509_ParseGeneralNames(uint8_t *encode, uint32_t encLen, BslList *
383 if (ret != BSL_SUCCESS) {383 if (ret != BSL_SUCCESS) {
384 break;384 break;
385 }385 }
386- if (nameValueLen == 0) {
387- continue;
388- }
389 // value386 // value
390- ret = ParseGeneralName(tag, &buff, &buffLen, nameValueLen, list);387+ uint8_t *nameBuff = buff;
388+ uint32_t nameBuffLen = nameValueLen;
389+ ret = ParseGeneralName(tag, &nameBuff, &nameBuffLen, nameValueLen, list);
391 if (ret != BSL_SUCCESS) {390 if (ret != BSL_SUCCESS) {
392 break;391 break;
393 }392 }
394- if (tag != HITLS_X509_GENERALNAME_DIR_TAG) {393+ if (tag == HITLS_X509_GENERALNAME_DIR_TAG && nameBuffLen != 0) {
395- buff += nameValueLen;394+ ret = HITLS_X509_ERR_PARSE_SAN_ITEM;
396- buffLen -= nameValueLen;395+ break;
397 }396 }
397+ buff += nameValueLen;
398+ buffLen -= nameValueLen;
398 }399 }
399 if (ret != BSL_SUCCESS) {400 if (ret != BSL_SUCCESS) {
400 HITLS_X509_ClearGeneralNames(list);401 HITLS_X509_ClearGeneralNames(list);
Mpki/x509_verify/src/hitls_x509_verify.c+29-16
@@ -1225,9 +1225,6 @@ static int32_t CheckMlKemKeyUsage(HITLS_X509_Cert *cert)
1225 1225 
1226static int32_t HITLS_X509_CheckCertExt(void *ctx, HITLS_X509_Cert *cert, int32_t depth)1226static int32_t HITLS_X509_CheckCertExt(void *ctx, HITLS_X509_Cert *cert, int32_t depth)
1227{1227{
1228- if (cert->tbs.version != 2) { // no ext v1 cert, 2 : X509 v3
1229- return HITLS_PKI_SUCCESS;
1230- }
1231#ifdef HITLS_PKI_X509_VFY_CB1228#ifdef HITLS_PKI_X509_VFY_CB
1232 HITLS_X509_StoreCtx *storeCtx = (HITLS_X509_StoreCtx *)ctx;1229 HITLS_X509_StoreCtx *storeCtx = (HITLS_X509_StoreCtx *)ctx;
1233 storeCtx->curCert = cert;1230 storeCtx->curCert = cert;
@@ -1235,6 +1232,12 @@ static int32_t HITLS_X509_CheckCertExt(void *ctx, HITLS_X509_Cert *cert, int32_t
1235#else1232#else
1236 (void)depth;1233 (void)depth;
1237#endif1234#endif
1235+ /* RFC5280 4.1.2.1: when extensions are used, as expected in this profile, version MUST be 3 (value is 2). */
1236+ if (cert->tbs.version < HITLS_X509_VERSION_3) {
1237+ VFYCBK_FAIL_IF(BSL_LIST_COUNT(cert->tbs.ext.extList) > 0,
1238+ (HITLS_X509_StoreCtx *)ctx, cert, depth, HITLS_X509_ERR_VFY_EXTENSIONS_REQUIRE_V3);
1239+ return HITLS_PKI_SUCCESS;
1240+ }
1238#if defined(HITLS_CRYPTO_MLDSA) || defined(HITLS_CRYPTO_SLH_DSA)1241#if defined(HITLS_CRYPTO_MLDSA) || defined(HITLS_CRYPTO_SLH_DSA)
1239 int32_t pqcSigKeyUsageRet = CheckPqcSigKeyUsage(cert);1242 int32_t pqcSigKeyUsageRet = CheckPqcSigKeyUsage(cert);
1240 if (pqcSigKeyUsageRet != HITLS_PKI_SUCCESS) {1243 if (pqcSigKeyUsageRet != HITLS_PKI_SUCCESS) {
@@ -1587,39 +1590,49 @@ static int32_t X509_GetVerifyCertChain(HITLS_X509_StoreCtx *storeCtx, HITLS_X509
1587int32_t X509_CheckExt(HITLS_X509_StoreCtx *storeCtx, HITLS_X509_List *chain)1590int32_t X509_CheckExt(HITLS_X509_StoreCtx *storeCtx, HITLS_X509_List *chain)
1588{1591{
1589 BslListNode *curNode = BSL_LIST_LastNode(chain);1592 BslListNode *curNode = BSL_LIST_LastNode(chain);
1590- int32_t depth = BSL_LIST_COUNT(chain) - 1;1593+ int32_t rootDepth = BSL_LIST_COUNT(chain) - 1;
1594+ int32_t curDepth = rootDepth;
1591 1595 
1592 while (curNode != NULL) {1596 while (curNode != NULL) {
1593 HITLS_X509_Cert *cur = (HITLS_X509_Cert *)BSL_LIST_GetData(curNode);1597 HITLS_X509_Cert *cur = (HITLS_X509_Cert *)BSL_LIST_GetData(curNode);
1594 HITLS_X509_CertExt *curExt = (HITLS_X509_CertExt *)cur->tbs.ext.extData;1598 HITLS_X509_CertExt *curExt = (HITLS_X509_CertExt *)cur->tbs.ext.extData;
1595 1599 
1596- if (depth > 0) {1600+ if (curDepth > 0) { // CA certificates (root and intermediate)
1597- /**1601+ /** RFC 5280 Section 6.1.4:
1598- * If the basic constraints extension is not present in a version 3 certificate,1602+ * (k) If certificate i is a version 3 certificate, verify that the basicConstraints extension is
1599- * or the extension is present but the cA boolean is not asserted,1603+ * present and that cA is set to TRUE. (If certificate i is a version 1 or version 2 certificate,
1600- * then the certified public key MUST NOT be used to verify certificate signatures.1604+ * then the application MUST either verify that certificate i is a CA certificate through
1605+ * out-of-band means or reject the certificate. Conforming implementations may choose to reject
1606+ * all version 1 and version 2 intermediate certificates.)
1601 */1607 */
1602- VFYCBK_FAIL_IF(((cur->tbs.version == HITLS_X509_VERSION_3) &&1608+ if (curDepth == rootDepth) {
1603- ((curExt->extFlags & HITLS_X509_EXT_FLAG_BCONS) == 0 || !curExt->isCa)),1609+ VFYCBK_FAIL_IF(((cur->tbs.version == HITLS_X509_VERSION_3) &&
1604- storeCtx, cur, depth, HITLS_X509_ERR_VFY_INVALID_CA);1610+ ((curExt->extFlags & HITLS_X509_EXT_FLAG_BCONS) == 0 || !curExt->isCa)),
1611+ storeCtx, cur, curDepth, HITLS_X509_ERR_VFY_INVALID_CA);
1612+ } else {
1613+ VFYCBK_FAIL_IF(cur->tbs.version != HITLS_X509_VERSION_3,
1614+ storeCtx, cur, curDepth, HITLS_X509_ERR_VFY_INTERCA_INVALID_VERSION);
1615+ VFYCBK_FAIL_IF((curExt->extFlags & HITLS_X509_EXT_FLAG_BCONS) == 0 || !curExt->isCa,
1616+ storeCtx, cur, curDepth, HITLS_X509_ERR_VFY_INTERCA_INVALID_BCONS);
1617+ }
1605 /**1618 /**
1606 * Conforming CAs MUST include this extension in certificates that contain public keys1619 * Conforming CAs MUST include this extension in certificates that contain public keys
1607 * that are used to validate digital signatures on other public key certificates or CRLs.1620 * that are used to validate digital signatures on other public key certificates or CRLs.
1608 */1621 */
1609 VFYCBK_FAIL_IF(((curExt->extFlags & HITLS_X509_EXT_FLAG_KUSAGE) != 0) &&1622 VFYCBK_FAIL_IF(((curExt->extFlags & HITLS_X509_EXT_FLAG_KUSAGE) != 0) &&
1610 ((curExt->keyUsage & HITLS_X509_EXT_KU_KEY_CERT_SIGN) == 0),1623 ((curExt->keyUsage & HITLS_X509_EXT_KU_KEY_CERT_SIGN) == 0),
1611- storeCtx, cur, depth, HITLS_X509_ERR_VFY_KU_NO_CERTSIGN);1624+ storeCtx, cur, curDepth, HITLS_X509_ERR_VFY_KU_NO_CERTSIGN);
1612 1625 
1613 if ((curExt->extFlags & HITLS_X509_EXT_FLAG_BCONS) != 0 && curExt->isCa && curExt->maxPathLen >= 0) {1626 if ((curExt->extFlags & HITLS_X509_EXT_FLAG_BCONS) != 0 && curExt->isCa && curExt->maxPathLen >= 0) {
1614- VFYCBK_FAIL_IF(curExt->maxPathLen < depth - 1, storeCtx, cur, depth,1627+ VFYCBK_FAIL_IF(curExt->maxPathLen < curDepth - 1, storeCtx, cur, curDepth,
1615 HITLS_X509_ERR_VFY_PATHLEN_EXCEEDED);1628 HITLS_X509_ERR_VFY_PATHLEN_EXCEEDED);
1616 }1629 }
1617 } else {1630 } else {
1618 int32_t ret = X509_VerifyUsageEE(storeCtx, cur);1631 int32_t ret = X509_VerifyUsageEE(storeCtx, cur);
1619- VFYCBK_FAIL_IF(ret != HITLS_PKI_SUCCESS, storeCtx, cur, depth, ret);1632+ VFYCBK_FAIL_IF(ret != HITLS_PKI_SUCCESS, storeCtx, cur, curDepth, ret);
1620 }1633 }
1621 curNode = BSL_LIST_GetPrevNode(curNode);1634 curNode = BSL_LIST_GetPrevNode(curNode);
1622- depth--;1635+ curDepth--;
1623 }1636 }
1624 return HITLS_PKI_SUCCESS;1637 return HITLS_PKI_SUCCESS;
1625}1638}
Mtestcode/sdv/testcase/pki/cert/test_suite_sdv_x509_check.c+51-0
@@ -1591,6 +1591,42 @@ EXIT:
1591}1591}
1592/* END_CASE */1592/* END_CASE */
1593 1593 
1594+/* BEGIN_CASE */
1595+void SDV_X509_CERT_WITH_SAN_PARSE_TEST_TC002(int isCritical, char *certPath, char *nameValue, int nameType)
1596+{
1597+ HITLS_X509_Cert *parsedCert = NULL;
1598+ HITLS_X509_ExtSan parsedSan = {0};
1599+ HITLS_X509_GeneralName *gn = NULL;
1600+ BslList *dnList = GenDNList();
1601+ uint32_t nameValueLen = (uint32_t)strlen(nameValue);
1602+ 
1603+ ASSERT_EQ(HITLS_X509_CertParseFile(BSL_FORMAT_ASN1, certPath, &parsedCert), HITLS_PKI_SUCCESS);
1604+ 
1605+ ASSERT_EQ(HITLS_X509_CertCtrl(parsedCert, HITLS_X509_EXT_GET_SAN, &parsedSan, sizeof(HITLS_X509_ExtSan)), 0);
1606+ ASSERT_EQ(parsedSan.critical, isCritical);
1607+ if (nameType == -1) {
1608+ ASSERT_EQ(BSL_LIST_COUNT(parsedSan.names), 0);
1609+ ASSERT_EQ(BSL_LIST_GET_FIRST(parsedSan.names), NULL);
1610+ } else {
1611+ ASSERT_TRUE(BSL_LIST_COUNT(parsedSan.names) >= 1);
1612+ gn = BSL_LIST_GET_FIRST(parsedSan.names);
1613+ ASSERT_EQ(gn->type, nameType);
1614+ ASSERT_EQ(gn->value.dataLen, nameValueLen);
1615+ if (nameValueLen > 0) {
1616+ ASSERT_COMPARE("subject Alternative Name", gn->value.data, gn->value.dataLen,
1617+ nameValue, nameValueLen);
1618+ }
1619+ }
1620+ ASSERT_TRUE(TestIsErrStackEmpty());
1621+ 
1622+EXIT:
1623+ TestRandDeInit();
1624+ HITLS_X509_CertFree(parsedCert);
1625+ HITLS_X509_DnListFree(dnList);
1626+ HITLS_X509_ClearSubjectAltName(&parsedSan);
1627+}
1628+/* END_CASE */
1629+ 
1594/* BEGIN_CASE */1630/* BEGIN_CASE */
1595void SDV_X509_CERT_WITH_SAN_ALL_PARSE_TC001(int isCritical, char *certPath, int isEdited)1631void SDV_X509_CERT_WITH_SAN_ALL_PARSE_TC001(int isCritical, char *certPath, int isEdited)
1596{1632{
@@ -1663,6 +1699,21 @@ EXIT:
1663}1699}
1664/* END_CASE */1700/* END_CASE */
1665 1701 
1702+/* BEGIN_CASE */
1703+void SDV_X509_CERT_WITH_ILLEGAL_SAN_DIRNAME_0_LEN_PARSE_TEST_TC001(char *certPath)
1704+{
1705+ HITLS_X509_Cert *parsedCert = NULL;
1706+ HITLS_X509_ExtSan parsedSan = {0};
1707+ ASSERT_EQ(HITLS_X509_CertParseFile(BSL_FORMAT_ASN1, certPath, &parsedCert), HITLS_PKI_SUCCESS);
1708+ ASSERT_NE(HITLS_X509_CertCtrl(parsedCert, HITLS_X509_EXT_GET_SAN,
1709+ &parsedSan, sizeof(HITLS_X509_ExtSan)), HITLS_PKI_SUCCESS);
1710+ 
1711+EXIT:
1712+ HITLS_X509_CertFree(parsedCert);
1713+ HITLS_X509_ClearSubjectAltName(&parsedSan);
1714+}
1715+/* END_CASE */
1716+ 
1666/* BEGIN_CASE */1717/* BEGIN_CASE */
1667void SDV_X509_CERT_WITH_BCON_GEN_TEST_TC001(int isCritical, int isCa, int maxPathLen,1718void SDV_X509_CERT_WITH_BCON_GEN_TEST_TC001(int isCritical, int isCa, int maxPathLen,
1668 int algId, int hashId, int curveId)1719 int algId, int hashId, int curveId)
Mtestcode/sdv/testcase/pki/cert/test_suite_sdv_x509_check.data+9-0
@@ -265,12 +265,21 @@ SDV_X509_CERT_WITH_SAN_PARSE_TEST_TC001:0:"../testdata/cert/asn1/certcheck/cert_
265SDV_X509_CERT_WITH_SAN_PARSE_TEST_TC001:uri265SDV_X509_CERT_WITH_SAN_PARSE_TEST_TC001:uri
266SDV_X509_CERT_WITH_SAN_PARSE_TEST_TC001:0:"../testdata/cert/asn1/certcheck/cert_ext_san_parse_7.der":1:"https://www.openhitls.com/api":HITLS_X509_GN_URI266SDV_X509_CERT_WITH_SAN_PARSE_TEST_TC001:0:"../testdata/cert/asn1/certcheck/cert_ext_san_parse_7.der":1:"https://www.openhitls.com/api":HITLS_X509_GN_URI
267 267 
268+SDV_X509_CERT_WITH_SAN_PARSE_TEST_TC002:san element 0 length
269+SDV_X509_CERT_WITH_SAN_PARSE_TEST_TC002:0:"../testdata/cert/asn1/certcheck/cert_ext_san_element_0_length.der":"":HITLS_X509_GN_DNS
270+ 
271+SDV_X509_CERT_WITH_SAN_PARSE_TEST_TC002:san no element
272+SDV_X509_CERT_WITH_SAN_PARSE_TEST_TC002:0:"../testdata/cert/asn1/certcheck/cert_ext_san_no_element.der":"":-1
273+ 
268SDV_X509_CERT_WITH_SAN_ALL_PARSE_TC001:all274SDV_X509_CERT_WITH_SAN_ALL_PARSE_TC001:all
269SDV_X509_CERT_WITH_SAN_ALL_PARSE_TC001:0:"../testdata/cert/asn1/certcheck/cert_ext_san_parse_8.der":1275SDV_X509_CERT_WITH_SAN_ALL_PARSE_TC001:0:"../testdata/cert/asn1/certcheck/cert_ext_san_parse_8.der":1
270 276 
271SDV_X509_CERT_WITH_ILLEGAL_SAN_PARSE_TEST_TC001:generalName is empty277SDV_X509_CERT_WITH_ILLEGAL_SAN_PARSE_TEST_TC001:generalName is empty
272SDV_X509_CERT_WITH_ILLEGAL_SAN_PARSE_TEST_TC001:0:"../testdata/cert/asn1/certcheck/cert_ext_san_parse_9.der":1278SDV_X509_CERT_WITH_ILLEGAL_SAN_PARSE_TEST_TC001:0:"../testdata/cert/asn1/certcheck/cert_ext_san_parse_9.der":1
273 279 
280+SDV_X509_CERT_WITH_ILLEGAL_SAN_DIRNAME_0_LEN_PARSE_TEST_TC001:directoryName with zero length
281+SDV_X509_CERT_WITH_ILLEGAL_SAN_DIRNAME_0_LEN_PARSE_TEST_TC001:"../testdata/cert/asn1/certcheck/cert_ext_san_dirname_0_length.der"
282+ 
274SDV_X509_CERT_WITH_BCON_GEN_TEST_TC001:critical, Ca, maxPathLen = 1283SDV_X509_CERT_WITH_BCON_GEN_TEST_TC001:critical, Ca, maxPathLen = 1
275SDV_X509_CERT_WITH_BCON_GEN_TEST_TC001:1:1:1:CRYPT_PKEY_RSA:CRYPT_MD_SHA256:0284SDV_X509_CERT_WITH_BCON_GEN_TEST_TC001:1:1:1:CRYPT_PKEY_RSA:CRYPT_MD_SHA256:0
276 285 
Mtestcode/sdv/testcase/pki/common/test_suite_sdv_common.c+54-0
@@ -2695,6 +2695,60 @@ EXIT:
2695}2695}
2696/* END_CASE */2696/* END_CASE */
2697 2697 
2698+/**
2699+ * @test SDV_PKI_VERIFY_HOSTNAME_SAN_ZERO_LEN_TC001
2700+ * @title Hostname verification with zero-length SAN DNS entry
2701+ */
2702+/* BEGIN_CASE */
2703+void SDV_PKI_VERIFY_HOSTNAME_SAN_ZERO_LEN_TC001(char *certPath)
2704+{
2705+#if defined(HITLS_PKI_X509_CRT_PARSE) && defined(HITLS_PKI_X509_VFY_IDENTITY)
2706+ TestMemInit();
2707+ HITLS_X509_Cert *cert = NULL;
2708+ HITLS_X509_ExtSan san = {0};
2709+ bool hasZeroLenDns = false;
2710+ 
2711+ // Certificate parses successfully (zero-length entry not rejected).
2712+ ASSERT_EQ(HITLS_X509_CertParseFile(BSL_FORMAT_ASN1, certPath, &cert), HITLS_PKI_SUCCESS);
2713+ ASSERT_NE(cert, NULL);
2714+ 
2715+ // SAN list contains 4 entries including a zero-length DNS entry.
2716+ ASSERT_EQ(HITLS_X509_CertCtrl(cert, HITLS_X509_EXT_GET_SAN, &san, sizeof(HITLS_X509_ExtSan)), HITLS_PKI_SUCCESS);
2717+ ASSERT_EQ(BSL_LIST_COUNT(san.names), 4); //
2718+ for (BslListNode *node = BSL_LIST_FirstNode(san.names); node != NULL;
2719+ node = BSL_LIST_GetNextNode(san.names, node)) {
2720+ HITLS_X509_GeneralName *gn = (HITLS_X509_GeneralName *)BSL_LIST_GetData(node);
2721+ if (gn != NULL && gn->type == HITLS_X509_GN_DNS && gn->value.dataLen == 0) {
2722+ hasZeroLenDns = true;
2723+ }
2724+ }
2725+ ASSERT_TRUE(hasZeroLenDns);
2726+ 
2727+ // "test.example.com" matches via "*.example.com".
2728+ ASSERT_EQ(HITLS_X509_VerifyHostname(cert, 0, "test.example.com", strlen("test.example.com")), HITLS_PKI_SUCCESS);
2729+ ASSERT_EQ(HITLS_X509_VerifyHostname(cert, HITLS_X509_FLAG_VFY_WITH_PARTIAL_WILDCARD,
2730+ "test.example.com", strlen("test.example.com")), HITLS_PKI_SUCCESS);
2731+ 
2732+ // "example.com" does NOT match (CN fallback not triggered because SAN has DNS).
2733+ ASSERT_EQ(HITLS_X509_VerifyHostname(cert, 0, "example.com", strlen("example.com")),
2734+ HITLS_X509_ERR_VFY_HOSTNAME_FAIL);
2735+ TestErrClear();
2736+ ASSERT_EQ(HITLS_X509_VerifyHostname(cert, HITLS_X509_FLAG_VFY_WITH_PARTIAL_WILDCARD,
2737+ "example.com", strlen("example.com")), HITLS_X509_ERR_VFY_HOSTNAME_FAIL);
2738+ TestErrClear();
2739+ 
2740+ ASSERT_TRUE(TestIsErrStackEmpty());
2741+ 
2742+EXIT:
2743+ HITLS_X509_ClearSubjectAltName(&san);
2744+ HITLS_X509_CertFree(cert);
2745+#else
2746+ (void)certPath;
2747+ SKIP_TEST();
2748+#endif
2749+}
2750+/* END_CASE */
2751+ 
2698/**2752/**
2699 * @test SDV_X509_PARSE_NAME_LIST_UTF8_CACHE_TC0012753 * @test SDV_X509_PARSE_NAME_LIST_UTF8_CACHE_TC001
2700 * @title Parsed name UTF-8 canonical cache test2754 * @title Parsed name UTF-8 canonical cache test
Mtestcode/sdv/testcase/pki/common/test_suite_sdv_common.data+9-0
@@ -422,6 +422,12 @@ SDV_X509_EXT_ParseGeneralNames_Error_TC001:"8208746573742E636F":BSL_ASN1_ERR_DEC
422SDV_X509_EXT_ParseGeneralNames_Error_TC001: Unkown name tag422SDV_X509_EXT_ParseGeneralNames_Error_TC001: Unkown name tag
423SDV_X509_EXT_ParseGeneralNames_Error_TC001:"8008746573742E636F6D":HITLS_X509_ERR_PARSE_SAN_ITEM_UNKNOW423SDV_X509_EXT_ParseGeneralNames_Error_TC001:"8008746573742E636F6D":HITLS_X509_ERR_PARSE_SAN_ITEM_UNKNOW
424 424 
425+SDV_X509_EXT_ParseGeneralNames_Error_TC001: directoryName with zero length
426+SDV_X509_EXT_ParseGeneralNames_Error_TC001:"A400":BSL_INVALID_ARG
427+ 
428+SDV_X509_EXT_ParseGeneralNames_Error_TC001: directoryName declared length larger than actual content
429+SDV_X509_EXT_ParseGeneralNames_Error_TC001:"A44F304B310B300906035504061302554B31183016060355040A0C0F4D79204F7267616E697A6174696F6E3110300E060355040B0C074D7920556E69743110300E06035504030C074D79204E616D650000":HITLS_X509_ERR_PARSE_SAN_ITEM
430+ 
425SDV_X509_EXT_ParseSki_TC001: success431SDV_X509_EXT_ParseSki_TC001: success
426SDV_X509_EXT_ParseSki_TC001:"0414BFCB55F18843C3EF58D4D145E373762B7D151DB0":HITLS_PKI_SUCCESS:"BFCB55F18843C3EF58D4D145E373762B7D151DB0"432SDV_X509_EXT_ParseSki_TC001:"0414BFCB55F18843C3EF58D4D145E373762B7D151DB0":HITLS_PKI_SUCCESS:"BFCB55F18843C3EF58D4D145E373762B7D151DB0"
427 433 
@@ -860,6 +866,9 @@ SDV_PKI_VERIFY_HOSTNAME_WITH_CN_TC001:CRYPT_PKEY_ECDSA:BSL_FORMAT_ASN1:"3082059A
860SDV_PKI_VERIFY_HOSTNAME_WITH_CN_TC001: cert has no Subject Alternative Name, but has cn, flag = partial Wildcard866SDV_PKI_VERIFY_HOSTNAME_WITH_CN_TC001: cert has no Subject Alternative Name, but has cn, flag = partial Wildcard
861SDV_PKI_VERIFY_HOSTNAME_WITH_CN_TC001:CRYPT_PKEY_ECDSA:BSL_FORMAT_ASN1:"3082059A30820482A00302010202100DC95EA1BD220000000072D70C6C8595300D06092A864886F70D01010B0500303D310B300906035504061302434831123010060355040A1309546573742043657274311A301806035504031311777777206F70656E6869746C7320636F6D301E170D3235303632363030303030305A170D3235303932343233353935395A306A310B3009060355040613024348310E300C060355040813056368696E61311430120603550407130B68656C6C6F20776F726C64311B3019060355040A1312666F722074657374206F70656E6869746C733118301606035504030C0F2A2E6F70656E6869746C732E636F6D3059301306072A8648CE3D020106082A8648CE3D030107034200042923EEA24672F8ECE66EA99597FB7EBFF8516985E2FAAE05F78B22550216889A9940E8819D61E24DC512F3C63621701B2374744D630E47851EE82B8732956DD7A38203323082032E301F0603551D23041830168014748580C066C7DF370000000000AA031DBEEDCD17301D0603551D0E041604148ECE54DB00000000002AFE6763D64199828A1BF5304A0603551D2004433041303F060667810C0102023035303306082B06010505070201162768747470733A2F2F676974636F64652E636F6D2F6F70656E4869544C532F6F70656E6869746C73300E0603551D0F0101FF040403020388301D0603551D250416301406082B0601050507030106082B0601050507030230670603551D1F0460305E302DA02BA029862768747470733A2F2F676974636F64652E636F6D2F6F70656E4869544C532F6F70656E6869746C73302DA02BA029862768747470733A2F2F676974636F64652E636F6D2F6F70656E4869544C532F6F70656E6869746C73307806082B06010505070101046C306A303306082B06010505073001862768747470733A2F2F676974636F64652E636F6D2F6F70656E4869544C532F6F70656E6869746C73303306082B06010505073002862768747470733A2F2F676974636F64652E636F6D2F6F70656E4869544C532F6F70656E6869746C73300C0603551D130101FF040230003082017E060A2B06010401D6790204020482016E0482016A0168007500DDDC003495D7E11605E79532FAC79FF83D1C00DFDB003A1412760A2CACBBC82A00000097A99BDE320000040300463044022000521DDF121D0D505B968854FB65FFD3006772D618DF11E0F194549F33D40DC60020034A74A3D91E98E407C40BFCBDF4004EC9FFFDC4E839F5E733D5DF50CC37004C007600ED3C4BD6E806C2A4A2005700CB24E23801DF512FEDC486C5700F2000B73E3FE000000197A99BDE3B000004000047304502204EA4AEA62FDF1031D700A115354FD9F0CDB836EC7D83CCC5CC00CF88CB1D605A022100F82B894E77EC002B73B4607F124C7CDAC08D8F0DD7AA00E5F87CF272B80565C1007700A442C500496061548F0FD4EA9CFB7A2D26454D00A97F2FDF4559F6274F3A845400000100A99BDE4300000403004830460221000024DD43FCBB213F700F98E49244D096003F5A44F3DA7271B39972DD6CC2BF09002100B621932342ACF1FCC043CAA7910012BAA80BA3DC59EC9FE24CA5FADFFD008C0B300D06092A864886F70D01010B05000382010100ADF2434900149CFE8C0025A116D1597E0A9BA1A900A4BA8A2700C23432644DE74619EBD000B70EDBFA00B7FD7C570CFBF9BB1BA300ACE36F7800C1B28AA0BB445CF3C38E006F71D364005EA731956E966A73082C00F401D9BD003AC15D40913DD6637B2E0015E0AA4700A73C386AAE5CD9FE77D8009075D4DF00488FE57B8E71D6701096003BD5BA370054CFCD624912B003B25300B160A38000B46F3940AAF1F9494DD700FDC354A100DBA05FF2C29A6A142160007549187800F68AE9D324643B4C587000EE33FC690038591992A5B9B7FF9221006F0BF97D007EE94717C8C63000607800BD5F96F000B5B12435688FB5105DF900799481FE006047E6CF71A1":0867SDV_PKI_VERIFY_HOSTNAME_WITH_CN_TC001:CRYPT_PKEY_ECDSA:BSL_FORMAT_ASN1:"3082059A30820482A00302010202100DC95EA1BD220000000072D70C6C8595300D06092A864886F70D01010B0500303D310B300906035504061302434831123010060355040A1309546573742043657274311A301806035504031311777777206F70656E6869746C7320636F6D301E170D3235303632363030303030305A170D3235303932343233353935395A306A310B3009060355040613024348310E300C060355040813056368696E61311430120603550407130B68656C6C6F20776F726C64311B3019060355040A1312666F722074657374206F70656E6869746C733118301606035504030C0F2A2E6F70656E6869746C732E636F6D3059301306072A8648CE3D020106082A8648CE3D030107034200042923EEA24672F8ECE66EA99597FB7EBFF8516985E2FAAE05F78B22550216889A9940E8819D61E24DC512F3C63621701B2374744D630E47851EE82B8732956DD7A38203323082032E301F0603551D23041830168014748580C066C7DF370000000000AA031DBEEDCD17301D0603551D0E041604148ECE54DB00000000002AFE6763D64199828A1BF5304A0603551D2004433041303F060667810C0102023035303306082B06010505070201162768747470733A2F2F676974636F64652E636F6D2F6F70656E4869544C532F6F70656E6869746C73300E0603551D0F0101FF040403020388301D0603551D250416301406082B0601050507030106082B0601050507030230670603551D1F0460305E302DA02BA029862768747470733A2F2F676974636F64652E636F6D2F6F70656E4869544C532F6F70656E6869746C73302DA02BA029862768747470733A2F2F676974636F64652E636F6D2F6F70656E4869544C532F6F70656E6869746C73307806082B06010505070101046C306A303306082B06010505073001862768747470733A2F2F676974636F64652E636F6D2F6F70656E4869544C532F6F70656E6869746C73303306082B06010505073002862768747470733A2F2F676974636F64652E636F6D2F6F70656E4869544C532F6F70656E6869746C73300C0603551D130101FF040230003082017E060A2B06010401D6790204020482016E0482016A0168007500DDDC003495D7E11605E79532FAC79FF83D1C00DFDB003A1412760A2CACBBC82A00000097A99BDE320000040300463044022000521DDF121D0D505B968854FB65FFD3006772D618DF11E0F194549F33D40DC60020034A74A3D91E98E407C40BFCBDF4004EC9FFFDC4E839F5E733D5DF50CC37004C007600ED3C4BD6E806C2A4A2005700CB24E23801DF512FEDC486C5700F2000B73E3FE000000197A99BDE3B000004000047304502204EA4AEA62FDF1031D700A115354FD9F0CDB836EC7D83CCC5CC00CF88CB1D605A022100F82B894E77EC002B73B4607F124C7CDAC08D8F0DD7AA00E5F87CF272B80565C1007700A442C500496061548F0FD4EA9CFB7A2D26454D00A97F2FDF4559F6274F3A845400000100A99BDE4300000403004830460221000024DD43FCBB213F700F98E49244D096003F5A44F3DA7271B39972DD6CC2BF09002100B621932342ACF1FCC043CAA7910012BAA80BA3DC59EC9FE24CA5FADFFD008C0B300D06092A864886F70D01010B05000382010100ADF2434900149CFE8C0025A116D1597E0A9BA1A900A4BA8A2700C23432644DE74619EBD000B70EDBFA00B7FD7C570CFBF9BB1BA300ACE36F7800C1B28AA0BB445CF3C38E006F71D364005EA731956E966A73082C00F401D9BD003AC15D40913DD6637B2E0015E0AA4700A73C386AAE5CD9FE77D8009075D4DF00488FE57B8E71D6701096003BD5BA370054CFCD624912B003B25300B160A38000B46F3940AAF1F9494DD700FDC354A100DBA05FF2C29A6A142160007549187800F68AE9D324643B4C587000EE33FC690038591992A5B9B7FF9221006F0BF97D007EE94717C8C63000607800BD5F96F000B5B12435688FB5105DF900799481FE006047E6CF71A1":0
862 868 
869+SDV_PKI_VERIFY_HOSTNAME_SAN_ZERO_LEN_TC001: hostname verification with zero-length SAN DNS entry
870+SDV_PKI_VERIFY_HOSTNAME_SAN_ZERO_LEN_TC001:"../testdata/cert/asn1/certcheck/cert_ext_san_element_0_length.der"
871+ 
863SDV_X509_CRL_PARSE_NAME_LIST_TC001 HITLS_X509_ParseNameNode encounters the error BSL_ASN1_ERR_DECODE_LEN at the start872SDV_X509_CRL_PARSE_NAME_LIST_TC001 HITLS_X509_ParseNameNode encounters the error BSL_ASN1_ERR_DECODE_LEN at the start
864SDV_X509_CRL_PARSE_NAME_LIST_TC001:"3100310031023000"873SDV_X509_CRL_PARSE_NAME_LIST_TC001:"3100310031023000"
865 874 
Mtestcode/sdv/testcase/pki/verify/test_suite_sdv_x509_vfy.c+125-4
@@ -1683,10 +1683,10 @@ void SDV_X509_VERIFY_CERT_CHAIN_FUNC_TC001(void)
1683 ASSERT_TRUE(TestIsErrStackEmpty());1683 ASSERT_TRUE(TestIsErrStackEmpty());
1684 HITLS_X509_CertExt *certExt = (HITLS_X509_CertExt *)ca->tbs.ext.extData;1684 HITLS_X509_CertExt *certExt = (HITLS_X509_CertExt *)ca->tbs.ext.extData;
1685 certExt->extFlags &= ~HITLS_X509_EXT_FLAG_BCONS;1685 certExt->extFlags &= ~HITLS_X509_EXT_FLAG_BCONS;
1686- ASSERT_EQ(HITLS_X509_CertVerify(store, chain), HITLS_X509_ERR_VFY_INVALID_CA);1686+ ASSERT_EQ(HITLS_X509_CertVerify(store, chain), HITLS_X509_ERR_VFY_INTERCA_INVALID_BCONS);
1687 certExt->extFlags |= HITLS_X509_EXT_FLAG_BCONS;1687 certExt->extFlags |= HITLS_X509_EXT_FLAG_BCONS;
1688 certExt->isCa = false;1688 certExt->isCa = false;
1689- ASSERT_EQ(HITLS_X509_CertVerify(store, chain), HITLS_X509_ERR_VFY_INVALID_CA);1689+ ASSERT_EQ(HITLS_X509_CertVerify(store, chain), HITLS_X509_ERR_VFY_INTERCA_INVALID_BCONS);
1690 certExt->isCa = true;1690 certExt->isCa = true;
1691 certExt->extFlags |= HITLS_X509_EXT_FLAG_KUSAGE;1691 certExt->extFlags |= HITLS_X509_EXT_FLAG_KUSAGE;
1692 certExt->keyUsage &= ~HITLS_X509_EXT_KU_KEY_CERT_SIGN;1692 certExt->keyUsage &= ~HITLS_X509_EXT_KU_KEY_CERT_SIGN;
@@ -3598,7 +3598,7 @@ void SDV_X509_VFY_BC_MISSING_FAIL_TC001(void)
3598 ASSERT_TRUE(TestIsErrStackEmpty());3598 ASSERT_TRUE(TestIsErrStackEmpty());
3599 3599 
3600 int32_t ret = HITLS_X509_CertVerify(store, chain);3600 int32_t ret = HITLS_X509_CertVerify(store, chain);
3601- ASSERT_EQ(ret, HITLS_X509_ERR_VFY_INVALID_CA);3601+ ASSERT_EQ(ret, HITLS_X509_ERR_VFY_INTERCA_INVALID_BCONS);
3602 3602 
3603EXIT:3603EXIT:
3604 HITLS_X509_StoreCtxFree(store);3604 HITLS_X509_StoreCtxFree(store);
@@ -3644,7 +3644,7 @@ void SDV_X509_VFY_BC_CA_FALSE_FAIL_TC002(void)
3644 ASSERT_TRUE(TestIsErrStackEmpty());3644 ASSERT_TRUE(TestIsErrStackEmpty());
3645 3645 
3646 int32_t ret = HITLS_X509_CertVerify(store, chain);3646 int32_t ret = HITLS_X509_CertVerify(store, chain);
3647- ASSERT_EQ(ret, HITLS_X509_ERR_VFY_INVALID_CA);3647+ ASSERT_EQ(ret, HITLS_X509_ERR_VFY_INTERCA_INVALID_BCONS);
3648 3648 
3649EXIT:3649EXIT:
3650 HITLS_X509_StoreCtxFree(store);3650 HITLS_X509_StoreCtxFree(store);
@@ -5277,3 +5277,124 @@ EXIT:
5277 BSL_LIST_FREE(chain, (BSL_LIST_PFUNC_FREE)HITLS_X509_CertFree);5277 BSL_LIST_FREE(chain, (BSL_LIST_PFUNC_FREE)HITLS_X509_CertFree);
5278}5278}
5279/* END_CASE */5279/* END_CASE */
5280+ 
5281+/**
5282+ * @test SDV_X509_VFY_EXTENSIONS_REQUIRE_V3_TC001
5283+ * @title Reject v1/v2 certificates carrying extensions during verification.
5284+ * @brief Non-v3 certificates that carry X.509 extensions must be rejected in the verification phase
5285+ * @expect HITLS_X509_ERR_VFY_EXTENSIONS_REQUIRE_V3 for non-v3-with-extensions certs.
5286+ */
5287+/* BEGIN_CASE */
5288+void SDV_X509_VFY_EXTENSIONS_REQUIRE_V3_TC001(char *leafPath, char *interPath, char *rootPath, int exp)
5289+{
5290+#ifdef HITLS_PKI_X509_VFY_CB
5291+ TestMemInit();
5292+ HITLS_X509_Cert *root = NULL;
5293+ HITLS_X509_Cert *inter = NULL;
5294+ HITLS_X509_Cert *leaf = NULL;
5295+ int32_t (*testCallback)(int32_t, HITLS_X509_StoreCtx*) = X509StoreCtrlCbkSuc;
5296+ uint64_t flag = HITLS_X509_VFY_FLAG_DISABLE_TIME_CHECK;
5297+ 
5298+ HITLS_X509_StoreCtx *storeCtx = HITLS_X509_StoreCtxNew();
5299+ HITLS_X509_List *chain = BSL_LIST_New(sizeof(HITLS_X509_Cert *));
5300+ ASSERT_TRUE(storeCtx != NULL && chain != NULL);
5301+ 
5302+ ASSERT_EQ(HITLS_X509_CertParseFile(BSL_FORMAT_ASN1, leafPath, &leaf), HITLS_PKI_SUCCESS);
5303+ ASSERT_EQ(HITLS_X509_CertParseFile(BSL_FORMAT_ASN1, rootPath, &root), HITLS_PKI_SUCCESS);
5304+ 
5305+ ASSERT_EQ(X509_AddCertToChainTest(chain, leaf), HITLS_PKI_SUCCESS);
5306+ if (strlen(interPath) > 0) {
5307+ ASSERT_EQ(HITLS_X509_CertParseFile(BSL_FORMAT_ASN1, interPath, &inter), HITLS_PKI_SUCCESS);
5308+ ASSERT_EQ(X509_AddCertToChainTest(chain, inter), HITLS_PKI_SUCCESS);
5309+ }
5310+ ASSERT_EQ(X509_AddCertToChainTest(chain, root), HITLS_PKI_SUCCESS);
5311+ 
5312+ ASSERT_EQ(HITLS_X509_StoreCtxCtrl(storeCtx, HITLS_X509_STORECTX_DEEP_COPY_SET_CA, root, sizeof(HITLS_X509_Cert)), 0);
5313+ ASSERT_EQ(HITLS_X509_StoreCtxCtrl(storeCtx, HITLS_X509_STORECTX_SET_PARAM_FLAGS, &flag, sizeof(flag)), 0);
5314+ 
5315+ ASSERT_EQ(HITLS_X509_CertVerify(storeCtx, chain), exp);
5316+ if (exp != HITLS_PKI_SUCCESS) {
5317+ ASSERT_EQ(HITLS_X509_StoreCtxCtrl(storeCtx, HITLS_X509_STORECTX_SET_VERIFY_CB,
5318+ testCallback, sizeof(testCallback)), HITLS_PKI_SUCCESS);
5319+ ASSERT_EQ(HITLS_X509_CertVerify(storeCtx, chain), HITLS_PKI_SUCCESS);
5320+ }
5321+EXIT:
5322+ HITLS_X509_StoreCtxFree(storeCtx);
5323+ if (chain != NULL) {
5324+ BSL_LIST_FREE(chain, (BSL_LIST_PFUNC_FREE)HITLS_X509_CertFree);
5325+ }
5326+ HITLS_X509_CertFree(leaf);
5327+ HITLS_X509_CertFree(inter);
5328+ HITLS_X509_CertFree(root);
5329+#else
5330+ (void)leafPath;
5331+ (void)interPath;
5332+ (void)rootPath;
5333+ (void)exp;
5334+ SKIP_TEST();
5335+#endif
5336+}
5337+/* END_CASE */
5338+ 
5339+/**
5340+ * @test SDV_X509_VFY_V1_INTER_CA_TC001
5341+ * @title v1/v2 non-trust-anchor intermediate CAs must be rejected; v1 trust anchors must be accepted.
5342+ * @brief
5343+ * TC1: v1 intermediate (no extensions) in chain → HITLS_X509_ERR_VFY_INVALID_CA
5344+ * TC2: v2 intermediate (no extensions) in chain → HITLS_X509_ERR_VFY_INVALID_CA
5345+ * TC3: v1 self-signed root (no extensions) as trust anchor → HITLS_PKI_SUCCESS
5346+ * @expect
5347+ * TC1/TC2: HITLS_X509_ERR_VFY_INVALID_CA
5348+ * TC3: HITLS_PKI_SUCCESS
5349+ */
5350+/* BEGIN_CASE */
5351+void SDV_X509_VFY_V1_INTER_CA_TC001(char *leafPath, char *interPath, char *rootPath, int exp)
5352+{
5353+#ifdef HITLS_PKI_X509_VFY_CB
5354+ TestMemInit();
5355+ HITLS_X509_Cert *root = NULL;
5356+ HITLS_X509_Cert *inter = NULL;
5357+ HITLS_X509_Cert *leaf = NULL;
5358+ int32_t (*testCallback)(int32_t, HITLS_X509_StoreCtx*) = X509StoreCtrlCbkSuc;
5359+ uint64_t flag = HITLS_X509_VFY_FLAG_DISABLE_TIME_CHECK;
5360+ 
5361+ HITLS_X509_StoreCtx *storeCtx = HITLS_X509_StoreCtxNew();
5362+ HITLS_X509_List *chain = BSL_LIST_New(sizeof(HITLS_X509_Cert *));
5363+ ASSERT_TRUE(storeCtx != NULL && chain != NULL);
5364+ 
5365+ ASSERT_EQ(HITLS_X509_CertParseFile(BSL_FORMAT_UNKNOWN, leafPath, &leaf), HITLS_PKI_SUCCESS);
5366+ ASSERT_EQ(HITLS_X509_CertParseFile(BSL_FORMAT_UNKNOWN, rootPath, &root), HITLS_PKI_SUCCESS);
5367+ 
5368+ ASSERT_EQ(X509_AddCertToChainTest(chain, leaf), HITLS_PKI_SUCCESS);
5369+ if (strlen(interPath) > 0) {
5370+ ASSERT_EQ(HITLS_X509_CertParseFile(BSL_FORMAT_UNKNOWN, interPath, &inter), HITLS_PKI_SUCCESS);
5371+ ASSERT_EQ(X509_AddCertToChainTest(chain, inter), HITLS_PKI_SUCCESS);
5372+ }
5373+ ASSERT_EQ(X509_AddCertToChainTest(chain, root), HITLS_PKI_SUCCESS);
5374+ 
5375+ ASSERT_EQ(HITLS_X509_StoreCtxCtrl(storeCtx, HITLS_X509_STORECTX_DEEP_COPY_SET_CA, root, sizeof(HITLS_X509_Cert)), 0);
5376+ ASSERT_EQ(HITLS_X509_StoreCtxCtrl(storeCtx, HITLS_X509_STORECTX_SET_PARAM_FLAGS, &flag, sizeof(flag)), 0);
5377+ 
5378+ ASSERT_EQ(HITLS_X509_CertVerify(storeCtx, chain), exp);
5379+ if (exp != HITLS_PKI_SUCCESS) {
5380+ ASSERT_EQ(HITLS_X509_StoreCtxCtrl(storeCtx, HITLS_X509_STORECTX_SET_VERIFY_CB,
5381+ testCallback, sizeof(testCallback)), HITLS_PKI_SUCCESS);
5382+ ASSERT_EQ(HITLS_X509_CertVerify(storeCtx, chain), HITLS_PKI_SUCCESS);
5383+ }
5384+EXIT:
5385+ HITLS_X509_StoreCtxFree(storeCtx);
5386+ if (chain != NULL) {
5387+ BSL_LIST_FREE(chain, (BSL_LIST_PFUNC_FREE)HITLS_X509_CertFree);
5388+ }
5389+ HITLS_X509_CertFree(leaf);
5390+ HITLS_X509_CertFree(inter);
5391+ HITLS_X509_CertFree(root);
5392+#else
5393+ (void)leafPath;
5394+ (void)interPath;
5395+ (void)rootPath;
5396+ (void)exp;
5397+ SKIP_TEST();
5398+#endif
5399+}
5400+/* END_CASE */
Mtestcode/sdv/testcase/pki/verify/test_suite_sdv_x509_vfy.data+30-0
@@ -478,3 +478,33 @@ SDV_X509_SECBITS_COMBINED_TC001:"../testdata/cert/chain/secbits/h_mldsa44_leaf.d
478 478 
479SDV_X509_SECBITS_COMBINED_TC001: H_256: secbits=256, Root:256>=256 PASS, Inter:192<256 FAIL, Leaf:128<256 FAIL479SDV_X509_SECBITS_COMBINED_TC001: H_256: secbits=256, Root:256>=256 PASS, Inter:192<256 FAIL, Leaf:128<256 FAIL
480SDV_X509_SECBITS_COMBINED_TC001:"../testdata/cert/chain/secbits/h_mldsa44_leaf.der":"../testdata/cert/chain/secbits/h_mldsa65_inter.der":"../testdata/cert/chain/secbits/h_mldsa87_root.der":256:HITLS_X509_ERR_VFY_CHECK_SECBITS480SDV_X509_SECBITS_COMBINED_TC001:"../testdata/cert/chain/secbits/h_mldsa44_leaf.der":"../testdata/cert/chain/secbits/h_mldsa65_inter.der":"../testdata/cert/chain/secbits/h_mldsa87_root.der":256:HITLS_X509_ERR_VFY_CHECK_SECBITS
481+ 
482+SDV_X509_VFY_EXTENSIONS_REQUIRE_V3_TC001: TC1 v1 leaf with extensions
483+SDV_X509_VFY_EXTENSIONS_REQUIRE_V3_TC001:"../testdata/cert/chain/v3_exts/a_v1_ext_leaf.der":"":"../testdata/cert/chain/v3_exts/a_v3_root.der":HITLS_X509_ERR_VFY_EXTENSIONS_REQUIRE_V3
484+ 
485+SDV_X509_VFY_EXTENSIONS_REQUIRE_V3_TC001: TC2 v2 leaf with extensions
486+SDV_X509_VFY_EXTENSIONS_REQUIRE_V3_TC001:"../testdata/cert/chain/v3_exts/a_v2_ext_leaf.der":"":"../testdata/cert/chain/v3_exts/a_v3_root.der":HITLS_X509_ERR_VFY_EXTENSIONS_REQUIRE_V3
487+ 
488+SDV_X509_VFY_EXTENSIONS_REQUIRE_V3_TC001: TC3 v1 intermediate with extensions
489+SDV_X509_VFY_EXTENSIONS_REQUIRE_V3_TC001:"../testdata/cert/chain/v3_exts/a_v3_leaf.der":"../testdata/cert/chain/v3_exts/a_v1_ext_inter.der":"../testdata/cert/chain/v3_exts/a_v3_root.der":HITLS_X509_ERR_VFY_EXTENSIONS_REQUIRE_V3
490+ 
491+SDV_X509_VFY_EXTENSIONS_REQUIRE_V3_TC001: TC4 v2 intermediate with extensions
492+SDV_X509_VFY_EXTENSIONS_REQUIRE_V3_TC001:"../testdata/cert/chain/v3_exts/a_v3_leaf.der":"../testdata/cert/chain/v3_exts/a_v2_ext_inter.der":"../testdata/cert/chain/v3_exts/a_v3_root.der":HITLS_X509_ERR_VFY_EXTENSIONS_REQUIRE_V3
493+ 
494+SDV_X509_VFY_EXTENSIONS_REQUIRE_V3_TC001: TC5 v1 root with extensions as trust anchor
495+SDV_X509_VFY_EXTENSIONS_REQUIRE_V3_TC001:"../testdata/cert/chain/v3_exts/b_v3_leaf.der":"":"../testdata/cert/chain/v3_exts/b_v1_ext_root.der":HITLS_X509_ERR_VFY_EXTENSIONS_REQUIRE_V3
496+ 
497+SDV_X509_VFY_V1_INTER_CA_TC001: TC1 v1 intermediate without extensions rejected
498+SDV_X509_VFY_V1_INTER_CA_TC001:"../testdata/cert/chain/v1_inter/v3_leaf.der":"../testdata/cert/chain/v1_inter/v1_inter.der":"../testdata/cert/chain/v1_inter/v3_root.der":HITLS_X509_ERR_VFY_INTERCA_INVALID_VERSION
499+ 
500+SDV_X509_VFY_V1_INTER_CA_TC001: TC2 v2 intermediate without extensions rejected
501+SDV_X509_VFY_V1_INTER_CA_TC001:"../testdata/cert/chain/v1_inter/v3_leaf.der":"../testdata/cert/chain/v1_inter/v2_inter.der":"../testdata/cert/chain/v1_inter/v3_root.der":HITLS_X509_ERR_VFY_INTERCA_INVALID_VERSION
502+ 
503+SDV_X509_VFY_V1_INTER_CA_TC001: TC3 v1 trust anchor without extensions accepted
504+SDV_X509_VFY_V1_INTER_CA_TC001:"../testdata/cert/chain/v1_inter/v3_leaf_b.der":"":"../testdata/cert/chain/v1_inter/v1_root.der":HITLS_PKI_SUCCESS
505+ 
506+SDV_X509_VFY_V1_INTER_CA_TC001: TC4 v3 intermediate missing BasicConstraints
507+SDV_X509_VFY_V1_INTER_CA_TC001:"../testdata/cert/chain/bcExt/bc_leaf_missing_bc.pem":"../testdata/cert/chain/bcExt/bc_inter_missing_bc.pem":"../testdata/cert/chain/bcExt/bc_root_general.pem":HITLS_X509_ERR_VFY_INTERCA_INVALID_BCONS
508+ 
509+SDV_X509_VFY_V1_INTER_CA_TC001: TC5 v3 intermediate BasicConstraints CA=false
510+SDV_X509_VFY_V1_INTER_CA_TC001:"../testdata/cert/chain/bcExt/bc_leaf_ca_false.pem":"../testdata/cert/chain/bcExt/bc_inter_ca_false.pem":"../testdata/cert/chain/bcExt/bc_root_general.pem":HITLS_X509_ERR_VFY_INTERCA_INVALID_BCONS
Mtestcode/sdv/testcase/tls/consistency/tls13/test_suite_sdv_frame_tls13_consistency_rfc8446_cert.c+124-1
@@ -2432,4 +2432,127 @@ EXIT:
2432 FRAME_FreeLink(client);2432 FRAME_FreeLink(client);
2433 FRAME_FreeLink(server);2433 FRAME_FreeLink(server);
2434}2434}
2435-/* END_CASE */2435+/* END_CASE */
2436+ 
2437+/**
2438+ * Verify that SetAuthLevel propagates the TLS security level to the X509 verification layer secbits check,
2439+ * and SHA-1 signatures (63 bits < 80 bits) are correctly rejected
2440+ */
2441+/* BEGIN_CASE */
2442+void SDV_TLS13_SECBITS_AUTH_LEVEL_SHA1_FAIL_TC001(void)
2443+{
2444+ FRAME_Init();
2445+ HITLS_Config *config = HITLS_CFG_NewTLS13Config();
2446+ ASSERT_TRUE(config != NULL);
2447+ FRAME_CertInfo certInfo = {
2448+ "ecdsa_sha1/ca-nist521.der",
2449+ "ecdsa_sha1/inter-nist521.der",
2450+ "ecdsa_sha1/end384-sha1.der",
2451+ 0,
2452+ "ecdsa_sha1/end384-sha1.key.der",
2453+ 0,
2454+ };
2455+ FRAME_LinkObj *client = FRAME_CreateLinkWithCert(config, BSL_UIO_TCP, &certInfo);
2456+ ASSERT_TRUE(client != NULL);
2457+ FRAME_LinkObj *server = FRAME_CreateLinkWithCert(config, BSL_UIO_TCP, &certInfo);
2458+ ASSERT_TRUE(server != NULL);
2459+ HITLS_SetSecurityLevel(client->ssl, 1);
2460+ ASSERT_EQ(FRAME_CreateConnection(client, server, true, HS_STATE_BUTT),
2461+ HITLS_CERT_ERR_VERIFY_CERT_CHAIN);
2462+EXIT:
2463+ HITLS_CFG_FreeConfig(config);
2464+ FRAME_FreeLink(client);
2465+ FRAME_FreeLink(server);
2466+}
2467+/* END_CASE */
2468+ 
2469+/**
2470+ * When verifying security level 0, the secbits check is not triggered, and weak signature certificates can pass.
2471+ */
2472+/* BEGIN_CASE */
2473+void SDV_TLS13_SECBITS_AUTH_LEVEL_SHA1_LEVEL0_PASS_TC002(void)
2474+{
2475+ FRAME_Init();
2476+ HITLS_Config *config = HITLS_CFG_NewTLS13Config();
2477+ ASSERT_TRUE(config != NULL);
2478+ FRAME_CertInfo certInfo = {
2479+ "ecdsa_sha1/ca-nist521.der",
2480+ "ecdsa_sha1/inter-nist521.der",
2481+ "ecdsa_sha1/end384-sha1.der",
2482+ 0,
2483+ "ecdsa_sha1/end384-sha1.key.der",
2484+ 0,
2485+ };
2486+ FRAME_LinkObj *client = FRAME_CreateLinkWithCert(config, BSL_UIO_TCP, &certInfo);
2487+ ASSERT_TRUE(client != NULL);
2488+ FRAME_LinkObj *server = FRAME_CreateLinkWithCert(config, BSL_UIO_TCP, &certInfo);
2489+ ASSERT_TRUE(server != NULL);
2490+ ASSERT_EQ(FRAME_CreateConnection(client, server, true, HS_STATE_BUTT), HITLS_SUCCESS);
2491+EXIT:
2492+ HITLS_CFG_FreeConfig(config);
2493+ FRAME_FreeLink(client);
2494+ FRAME_FreeLink(server);
2495+}
2496+/* END_CASE */
2497+ 
2498+/**
2499+ * Verification of normally strong certificate chains passes verification at security level 2.
2500+ */
2501+/* BEGIN_CASE */
2502+void SDV_TLS13_SECBITS_AUTH_LEVEL_RSA_LEVEL2_PASS_TC003(void)
2503+{
2504+ FRAME_Init();
2505+ HITLS_Config *config = HITLS_CFG_NewTLS13Config();
2506+ ASSERT_TRUE(config != NULL);
2507+ FRAME_CertInfo certInfo = {
2508+ "rsa_sha/ca-3072.der",
2509+ "rsa_sha/inter-3072.der",
2510+ "rsa_sha/end-sha256.der",
2511+ 0,
2512+ "rsa_sha/end-sha256.key.der",
2513+ 0,
2514+ };
2515+ FRAME_LinkObj *client = FRAME_CreateLinkWithCert(config, BSL_UIO_TCP, &certInfo);
2516+ ASSERT_TRUE(client != NULL);
2517+ FRAME_LinkObj *server = FRAME_CreateLinkWithCert(config, BSL_UIO_TCP, &certInfo);
2518+ ASSERT_TRUE(server != NULL);
2519+ HITLS_SetSecurityLevel(client->ssl, 2);
2520+ HITLS_SetSecurityLevel(server->ssl, 2);
2521+ ASSERT_EQ(FRAME_CreateConnection(client, server, true, HS_STATE_BUTT), HITLS_SUCCESS);
2522+EXIT:
2523+ HITLS_CFG_FreeConfig(config);
2524+ FRAME_FreeLink(client);
2525+ FRAME_FreeLink(server);
2526+}
2527+/* END_CASE */
2528+ 
2529+/**
2530+ * Certificates with insufficient key strength are intercepted by the TLS layer key check when verifying at security level 3.
2531+ */
2532+/* BEGIN_CASE */
2533+void SDV_TLS13_SECBITS_AUTH_LEVEL_WEAK_KEY_FAIL_TC004(void)
2534+{
2535+ FRAME_Init();
2536+ HITLS_Config *config = HITLS_CFG_NewTLS13Config();
2537+ ASSERT_TRUE(config != NULL);
2538+ FRAME_CertInfo certInfo = {
2539+ "rsa_sha/ca-3072.der",
2540+ "rsa_sha/inter-3072.der",
2541+ "rsa_sha/end-sha256.der",
2542+ 0,
2543+ "rsa_sha/end-sha256.key.der",
2544+ 0,
2545+ };
2546+ FRAME_LinkObj *client = FRAME_CreateLinkWithCert(config, BSL_UIO_TCP, &certInfo);
2547+ ASSERT_TRUE(client != NULL);
2548+ FRAME_LinkObj *server = FRAME_CreateLinkWithCert(config, BSL_UIO_TCP, &certInfo);
2549+ ASSERT_TRUE(server != NULL);
2550+ HITLS_SetSecurityLevel(client->ssl, 3);
2551+ ASSERT_EQ(FRAME_CreateConnection(client, server, true, HS_STATE_BUTT),
2552+ HITLS_CERT_ERR_EE_KEY_WITH_INSECURE_SECBITS);
2553+EXIT:
2554+ HITLS_CFG_FreeConfig(config);
2555+ FRAME_FreeLink(client);
2556+ FRAME_FreeLink(server);
2557+}
2558+/* END_CASE */
Mtestcode/sdv/testcase/tls/consistency/tls13/test_suite_sdv_frame_tls13_consistency_rfc8446_cert.data+13-1
@@ -132,4 +132,16 @@ UT_TLS_TLS13_RFC8446_SIGALG_SELECT_TC001 ec prefer
132UT_TLS_TLS13_RFC8446_SIGALG_SELECT_TC001:1132UT_TLS_TLS13_RFC8446_SIGALG_SELECT_TC001:1
133 133 
134UT_TLS_TLS13_RFC8446_SIGALG_SELECT_TC001 rsa prefer134UT_TLS_TLS13_RFC8446_SIGALG_SELECT_TC001 rsa prefer
135-UT_TLS_TLS13_RFC8446_SIGALG_SELECT_TC001:0135+UT_TLS_TLS13_RFC8446_SIGALG_SELECT_TC001:0
136+ 
137+SDV_TLS13_SECBITS_AUTH_LEVEL_SHA1_FAIL_TC001
138+SDV_TLS13_SECBITS_AUTH_LEVEL_SHA1_FAIL_TC001:
139+ 
140+SDV_TLS13_SECBITS_AUTH_LEVEL_SHA1_LEVEL0_PASS_TC002
141+SDV_TLS13_SECBITS_AUTH_LEVEL_SHA1_LEVEL0_PASS_TC002:
142+ 
143+SDV_TLS13_SECBITS_AUTH_LEVEL_RSA_LEVEL2_PASS_TC003
144+SDV_TLS13_SECBITS_AUTH_LEVEL_RSA_LEVEL2_PASS_TC003:
145+ 
146+SDV_TLS13_SECBITS_AUTH_LEVEL_WEAK_KEY_FAIL_TC004
147+SDV_TLS13_SECBITS_AUTH_LEVEL_WEAK_KEY_FAIL_TC004:
Atestcode/testdata/cert/asn1/certcheck/cert_ext_san_dirname_0_length.der+0-0
Binary files do not support preview
Atestcode/testdata/cert/asn1/certcheck/cert_ext_san_element_0_length.der+0-0
Binary files do not support preview
Atestcode/testdata/cert/asn1/certcheck/cert_ext_san_no_element.der+0-0
Binary files do not support preview
Atestcode/testdata/cert/chain/v1_inter/gen_certs.py+301-0
@@ -0,0 +1,301 @@
1+#!/usr/bin/env python3
2+# -*- coding: utf-8 -*-
3+# This file is part of the openHiTLS project.
4+#
5+# openHiTLS is licensed under the Mulan PSL v2.
6+# You can use this software according to the terms and conditions of the Mulan PSL v2.
7+# You may obtain a copy of Mulan PSL v2 at:
8+#
9+# http://license.coscl.org.cn/MulanPSL2
10+#
11+# THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
12+# EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
13+# MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
14+# See the Mulan PSL v2 for more details.
15+"""
16+Generate test certificates for v1/v2 intermediate CA rejection tests (Problem 2 fix).
17+ 
18+Tests that v1/v2 non-trust-anchor intermediate CAs are rejected, while v1 trust anchors are accepted.
19+ 
20+Strategy for v1/v2 certs WITHOUT extensions:
21+ 1. Build a TBS without any extensions using the cryptography library
22+ 2. Sign to get a v3 cert (the library always outputs v3)
23+ 3. Patch the version byte in the TBS DER from 0x02 (v3) to 0x00 (v1) or 0x01 (v2)
24+ 4. Re-sign the patched TBS with the issuer's private key
25+ 5. Assemble the final Certificate SEQUENCE
26+ 
27+Output files:
28+ v3_root.der - v3 root CA (trust anchor, with BC:CA=TRUE, KU:keyCertSign)
29+ v1_inter.der - v1 intermediate WITHOUT extensions, signed by root (TC1)
30+ v2_inter.der - v2 intermediate WITHOUT extensions, signed by root (TC2)
31+ v3_leaf.der - v3 leaf cert, signed by intermediate's key (for TC1/TC2 chain)
32+ v1_root.der - v1 self-signed root WITHOUT extensions (TC3 trust anchor)
33+ v3_leaf_b.der - v3 leaf cert, signed by v1 root's key (for TC3 chain)
34+"""
35+ 
36+import os
37+import datetime
38+from cryptography import x509
39+from cryptography.x509.oid import NameOID
40+from cryptography.hazmat.primitives import hashes, serialization
41+from cryptography.hazmat.primitives.asymmetric import rsa, padding
42+ 
43+ 
44+def gen_key():
45+ return rsa.generate_private_key(public_exponent=65537, key_size=2048)
46+ 
47+ 
48+def make_root_cn():
49+ return x509.Name([
50+ x509.NameAttribute(NameOID.COUNTRY_NAME, "CN"),
51+ x509.NameAttribute(NameOID.ORGANIZATION_NAME, "V1InterTest"),
52+ x509.NameAttribute(NameOID.COMMON_NAME, "V1InterTest Root CA"),
53+ ])
54+ 
55+ 
56+def make_inter_cn():
57+ return x509.Name([
58+ x509.NameAttribute(NameOID.COUNTRY_NAME, "CN"),
59+ x509.NameAttribute(NameOID.ORGANIZATION_NAME, "V1InterTest"),
60+ x509.NameAttribute(NameOID.COMMON_NAME, "V1InterTest Intermediate"),
61+ ])
62+ 
63+ 
64+def make_leaf_cn():
65+ return x509.Name([
66+ x509.NameAttribute(NameOID.COUNTRY_NAME, "CN"),
67+ x509.NameAttribute(NameOID.ORGANIZATION_NAME, "V1InterTest"),
68+ x509.NameAttribute(NameOID.COMMON_NAME, "V1InterTest Leaf"),
69+ ])
70+ 
71+ 
72+def make_root_b_cn():
73+ return x509.Name([
74+ x509.NameAttribute(NameOID.COUNTRY_NAME, "CN"),
75+ x509.NameAttribute(NameOID.ORGANIZATION_NAME, "V1InterTest"),
76+ x509.NameAttribute(NameOID.COMMON_NAME, "V1InterTest SelfRoot"),
77+ ])
78+ 
79+ 
80+def build_ca_tbs(subject, issuer, pub_key, path_length):
81+ return (
82+ x509.CertificateBuilder()
83+ .subject_name(subject)
84+ .issuer_name(issuer)
85+ .public_key(pub_key)
86+ .serial_number(x509.random_serial_number())
87+ .not_valid_before(datetime.datetime(2024, 1, 1))
88+ .not_valid_after(datetime.datetime(2050, 12, 31))
89+ .add_extension(
90+ x509.BasicConstraints(ca=True, path_length=path_length),
91+ critical=True,
92+ )
93+ .add_extension(
94+ x509.KeyUsage(
95+ digital_signature=True, key_cert_sign=True, crl_sign=True,
96+ content_commitment=False, key_encipherment=False,
97+ data_encipherment=False, key_agreement=False,
98+ encipher_only=False, decipher_only=False,
99+ ),
100+ critical=True,
101+ )
102+ )
103+ 
104+ 
105+def build_leaf_tbs(subject, issuer, pub_key):
106+ return (
107+ x509.CertificateBuilder()
108+ .subject_name(subject)
109+ .issuer_name(issuer)
110+ .public_key(pub_key)
111+ .serial_number(x509.random_serial_number())
112+ .not_valid_before(datetime.datetime(2024, 1, 1))
113+ .not_valid_after(datetime.datetime(2050, 12, 31))
114+ .add_extension(
115+ x509.BasicConstraints(ca=False, path_length=None),
116+ critical=True,
117+ )
118+ .add_extension(
119+ x509.KeyUsage(
120+ digital_signature=True, key_encipherment=True,
121+ content_commitment=False, key_agreement=False,
122+ key_cert_sign=False, crl_sign=False,
123+ data_encipherment=False, encipher_only=False, decipher_only=False,
124+ ),
125+ critical=True,
126+ )
127+ )
128+ 
129+ 
130+def build_no_ext_tbs(subject, issuer, pub_key):
131+ """Build a TBS without any extensions. Used for v1/v2 certs."""
132+ return (
133+ x509.CertificateBuilder()
134+ .subject_name(subject)
135+ .issuer_name(issuer)
136+ .public_key(pub_key)
137+ .serial_number(x509.random_serial_number())
138+ .not_valid_before(datetime.datetime(2024, 1, 1))
139+ .not_valid_after(datetime.datetime(2050, 12, 31))
140+ )
141+ 
142+ 
143+def to_der(cert):
144+ return cert.public_bytes(serialization.Encoding.DER)
145+ 
146+ 
147+def patch_version_in_der(der_bytes, new_version):
148+ der = bytearray(der_bytes)
149+ pattern = bytes([0xA0, 0x03, 0x02, 0x01])
150+ idx = der.find(pattern)
151+ if idx < 0:
152+ raise ValueError("version field pattern not found in DER")
153+ der[idx + 4] = new_version
154+ return bytes(der)
155+ 
156+ 
157+def extract_tbs_der(cert_der):
158+ if cert_der[0] != 0x30:
159+ raise ValueError("expected SEQUENCE tag")
160+ idx = 1
161+ if cert_der[1] & 0x80:
162+ idx += 1 + (cert_der[1] & 0x7F)
163+ else:
164+ idx += 1
165+ tbs_start = idx
166+ if cert_der[idx] != 0x30:
167+ raise ValueError("expected TBS SEQUENCE tag")
168+ idx += 1
169+ if cert_der[idx] & 0x80:
170+ num_len_bytes = cert_der[idx] & 0x7F
171+ idx += 1
172+ tbs_content_len = int.from_bytes(cert_der[idx:idx + num_len_bytes], 'big')
173+ idx += num_len_bytes
174+ else:
175+ tbs_content_len = cert_der[idx]
176+ idx += 1
177+ tbs_end = idx + tbs_content_len
178+ return cert_der[tbs_start:tbs_end]
179+ 
180+ 
181+def extract_sig_alg_and_value(cert_der):
182+ idx = 1
183+ if cert_der[1] & 0x80:
184+ idx += 1 + (cert_der[1] & 0x7F)
185+ else:
186+ idx += 1
187+ if cert_der[idx] != 0x30:
188+ raise ValueError("expected TBS SEQUENCE")
189+ idx += 1
190+ if cert_der[idx] & 0x80:
191+ num_len_bytes = cert_der[idx] & 0x7F
192+ tbs_len = int.from_bytes(cert_der[idx + 1:idx + 1 + num_len_bytes], 'big')
193+ idx += 1 + num_len_bytes + tbs_len
194+ else:
195+ tbs_len = cert_der[idx]
196+ idx += 1 + tbs_len
197+ sig_alg_start = idx
198+ if cert_der[idx] != 0x30:
199+ raise ValueError("expected sigAlg SEQUENCE")
200+ idx += 1
201+ if cert_der[idx] & 0x80:
202+ num_len_bytes = cert_der[idx] & 0x7F
203+ sig_alg_len = int.from_bytes(cert_der[idx + 1:idx + 1 + num_len_bytes], 'big')
204+ idx += 1 + num_len_bytes + sig_alg_len
205+ else:
206+ sig_alg_len = cert_der[idx]
207+ idx += 1 + sig_alg_len
208+ sig_alg_end = idx
209+ sig_val_start = idx
210+ sig_val_end = len(cert_der)
211+ return cert_der[sig_alg_start:sig_alg_end], cert_der[sig_val_start:sig_val_end]
212+ 
213+ 
214+def _encode_length(length):
215+ if length < 0x80:
216+ return bytes([length])
217+ elif length < 0x100:
218+ return bytes([0x81, length])
219+ elif length < 0x10000:
220+ return bytes([0x82, (length >> 8) & 0xFF, length & 0xFF])
221+ else:
222+ return bytes([0x83, (length >> 16) & 0xFF, (length >> 8) & 0xFF, length & 0xFF])
223+ 
224+ 
225+def build_versioned_cert_no_ext(tbs_builder, signing_key, version):
226+ """Build a certificate without extensions, with a specific version (0=v1, 1=v2).
227+ 
228+ 1. Sign a v3 TBS (without extensions) to get a valid cert structure
229+ 2. Extract TBS DER
230+ 3. Patch version byte to desired value
231+ 4. Re-sign patched TBS
232+ 5. Assemble final certificate
233+ """
234+ v3_cert = tbs_builder.sign(signing_key, hashes.SHA256())
235+ v3_der = to_der(v3_cert)
236+ 
237+ tbs_der = extract_tbs_der(v3_der)
238+ patched_tbs = patch_version_in_der(tbs_der, version)
239+ 
240+ sig_alg_der, _ = extract_sig_alg_and_value(v3_der)
241+ 
242+ new_signature = signing_key.sign(patched_tbs, padding.PKCS1v15(), hashes.SHA256())
243+ sig_content = b'\x00' + new_signature
244+ sig_value_der = b'\x03' + _encode_length(len(sig_content)) + sig_content
245+ 
246+ inner = patched_tbs + sig_alg_der + sig_value_der
247+ cert_der = b'\x30' + _encode_length(len(inner)) + inner
248+ return cert_der
249+ 
250+ 
251+def save(der_bytes, filename, out_dir):
252+ path = os.path.join(out_dir, filename)
253+ with open(path, "wb") as f:
254+ f.write(der_bytes)
255+ print(f" wrote {filename} ({len(der_bytes)} bytes)")
256+ 
257+ 
258+def main():
259+ out_dir = os.path.dirname(os.path.abspath(__file__))
260+ 
261+ print("Generating keys...")
262+ root_key = gen_key()
263+ inter_key = gen_key()
264+ leaf_key = gen_key()
265+ root_b_key = gen_key()
266+ 
267+ root_name = make_root_cn()
268+ inter_name = make_inter_cn()
269+ leaf_name = make_leaf_cn()
270+ root_b_name = make_root_b_cn()
271+ 
272+ print("Generating certificates...")
273+ 
274+ # v3 root CA (trust anchor for TC1/TC2, with BC:CA=TRUE, KU:keyCertSign)
275+ a_root = build_ca_tbs(root_name, root_name, root_key.public_key(), 2).sign(root_key, hashes.SHA256())
276+ save(to_der(a_root), "v3_root.der", out_dir)
277+ 
278+ # v1 intermediate WITHOUT extensions, signed by root (TC1)
279+ tbs_inter_no_ext = build_no_ext_tbs(inter_name, root_name, inter_key.public_key())
280+ save(build_versioned_cert_no_ext(tbs_inter_no_ext, root_key, 0x00), "v1_inter.der", out_dir)
281+ 
282+ # v2 intermediate WITHOUT extensions, signed by root (TC2)
283+ save(build_versioned_cert_no_ext(tbs_inter_no_ext, root_key, 0x01), "v2_inter.der", out_dir)
284+ 
285+ # v3 leaf signed by intermediate's key (for TC1/TC2 chain)
286+ a_leaf = build_leaf_tbs(leaf_name, inter_name, leaf_key.public_key()).sign(inter_key, hashes.SHA256())
287+ save(to_der(a_leaf), "v3_leaf.der", out_dir)
288+ 
289+ # v1 self-signed root WITHOUT extensions (TC3 trust anchor)
290+ tbs_root_b_no_ext = build_no_ext_tbs(root_b_name, root_b_name, root_b_key.public_key())
291+ save(build_versioned_cert_no_ext(tbs_root_b_no_ext, root_b_key, 0x00), "v1_root.der", out_dir)
292+ 
293+ # v3 leaf signed by v1 root's key (for TC3 chain)
294+ b_leaf = build_leaf_tbs(leaf_name, root_b_name, leaf_key.public_key()).sign(root_b_key, hashes.SHA256())
295+ save(to_der(b_leaf), "v3_leaf_b.der", out_dir)
296+ 
297+ print("Done.")
298+ 
299+ 
300+if __name__ == "__main__":
301+ main()
Atestcode/testdata/cert/chain/v1_inter/v1_inter.der+0-0
Binary files do not support preview
Atestcode/testdata/cert/chain/v1_inter/v1_root.der+0-0
Binary files do not support preview
Atestcode/testdata/cert/chain/v1_inter/v2_inter.der+0-0
Binary files do not support preview
Atestcode/testdata/cert/chain/v1_inter/v3_leaf.der+0-0
Binary files do not support preview
Atestcode/testdata/cert/chain/v1_inter/v3_leaf_b.der+0-0
Binary files do not support preview
Atestcode/testdata/cert/chain/v1_inter/v3_root.der+0-0
Binary files do not support preview
Atestcode/testdata/cert/chain/v3_exts/a_v1_ext_inter.der+0-0
Binary files do not support preview
Atestcode/testdata/cert/chain/v3_exts/a_v1_ext_leaf.der+0-0
Binary files do not support preview
Atestcode/testdata/cert/chain/v3_exts/a_v2_ext_inter.der+0-0
Binary files do not support preview
Atestcode/testdata/cert/chain/v3_exts/a_v2_ext_leaf.der+0-0
Binary files do not support preview
Atestcode/testdata/cert/chain/v3_exts/a_v3_inter.der+0-0
Binary files do not support preview
Atestcode/testdata/cert/chain/v3_exts/a_v3_leaf.der+0-0
Binary files do not support preview
Atestcode/testdata/cert/chain/v3_exts/a_v3_root.der+0-0
Binary files do not support preview
Atestcode/testdata/cert/chain/v3_exts/b_v1_ext_root.der+0-0
Binary files do not support preview
Atestcode/testdata/cert/chain/v3_exts/b_v3_leaf.der+0-0
Binary files do not support preview
Atestcode/testdata/cert/chain/v3_exts/gen_certs.py+333-0
@@ -0,0 +1,333 @@
1+#!/usr/bin/env python3
2+# -*- coding: utf-8 -*-
3+# This file is part of the openHiTLS project.
4+#
5+# openHiTLS is licensed under the Mulan PSL v2.
6+# You can use this software according to the terms and conditions of the Mulan PSL v2.
7+# You may obtain a copy of Mulan PSL v2 at:
8+#
9+# http://license.coscl.org.cn/MulanPSL2
10+#
11+# THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
12+# EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
13+# MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
14+# See the Mulan PSL v2 for more details.
15+"""
16+Generate test certificates for TC1-TC5 of the EXTENSIONS_REQUIRE_V3 verification tests.
17+ 
18+Strategy: construct v1/v2 certificates with extensions by manually building DER:
19+ 1. Build a v3 TBS using the cryptography library (with extensions)
20+ 2. Patch the version byte in the TBS DER from 0x02 (v3) to 0x00 (v1) or 0x01 (v2)
21+ 3. Re-sign the patched TBS with the issuer's private key
22+ 4. Assemble the final Certificate SEQUENCE: [patched TBS, signatureAlgorithm, signatureValue]
23+ 
24+This produces v1/v2 certificates with extensions AND valid signatures, so both OpenSSL
25+and openHiTLS can parse them. OpenSSL should reject them with
26+X509_V_ERR_EXTENSIONS_REQUIRE_VERSION_3; openHiTLS should reject them with
27+HITLS_X509_ERR_VFY_EXTENSIONS_REQUIRE_V3.
28+ 
29+Output files:
30+ a_v3_root.der - v3 root CA (trust anchor for TC1-TC4)
31+ a_v1_ext_leaf.der - TC1: v1 leaf with extensions, valid signature from root
32+ a_v2_ext_leaf.der - TC2: v2 leaf with extensions, valid signature from root
33+ a_v3_inter.der - v3 intermediate CA, signed by root
34+ a_v3_leaf.der - v3 leaf, signed by intermediate (for TC3/TC4 chain)
35+ a_v1_ext_inter.der - TC3: v1 intermediate with extensions, valid signature from root
36+ a_v2_ext_inter.der - TC4: v2 intermediate with extensions, valid signature from root
37+ b_v1_ext_root.der - TC5: v1 root with extensions, valid self-signature
38+ b_v3_leaf.der - v3 leaf, signed by root B (for TC5 chain)
39+"""
40+ 
41+import os
42+import datetime
43+from cryptography import x509
44+from cryptography.x509.oid import NameOID
45+from cryptography.hazmat.primitives import hashes, serialization
46+from cryptography.hazmat.primitives.asymmetric import rsa, padding, utils
47+ 
48+ 
49+def gen_key():
50+ return rsa.generate_private_key(public_exponent=65537, key_size=2048)
51+ 
52+ 
53+def make_root_cn():
54+ return x509.Name([
55+ x509.NameAttribute(NameOID.COUNTRY_NAME, "CN"),
56+ x509.NameAttribute(NameOID.ORGANIZATION_NAME, "v3exts Test"),
57+ x509.NameAttribute(NameOID.COMMON_NAME, "v3exts Root CA"),
58+ ])
59+ 
60+ 
61+def make_inter_cn():
62+ return x509.Name([
63+ x509.NameAttribute(NameOID.COUNTRY_NAME, "CN"),
64+ x509.NameAttribute(NameOID.ORGANIZATION_NAME, "v3exts Test"),
65+ x509.NameAttribute(NameOID.COMMON_NAME, "v3exts Intermediate CA"),
66+ ])
67+ 
68+ 
69+def make_leaf_cn():
70+ return x509.Name([
71+ x509.NameAttribute(NameOID.COUNTRY_NAME, "CN"),
72+ x509.NameAttribute(NameOID.ORGANIZATION_NAME, "v3exts Test"),
73+ x509.NameAttribute(NameOID.COMMON_NAME, "v3exts Leaf"),
74+ ])
75+ 
76+ 
77+def make_root_b_cn():
78+ return x509.Name([
79+ x509.NameAttribute(NameOID.COUNTRY_NAME, "CN"),
80+ x509.NameAttribute(NameOID.ORGANIZATION_NAME, "v3exts Test"),
81+ x509.NameAttribute(NameOID.COMMON_NAME, "v3exts Root B CA"),
82+ ])
83+ 
84+ 
85+def build_ca_tbs(subject, issuer, pub_key, path_length):
86+ builder = (
87+ x509.CertificateBuilder()
88+ .subject_name(subject)
89+ .issuer_name(issuer)
90+ .public_key(pub_key)
91+ .serial_number(x509.random_serial_number())
92+ .not_valid_before(datetime.datetime(2024, 1, 1))
93+ .not_valid_after(datetime.datetime(2050, 12, 31))
94+ .add_extension(
95+ x509.BasicConstraints(ca=True, path_length=path_length),
96+ critical=True,
97+ )
98+ .add_extension(
99+ x509.KeyUsage(
100+ digital_signature=True, key_cert_sign=True, crl_sign=True,
101+ content_commitment=False, key_encipherment=False,
102+ data_encipherment=False, key_agreement=False,
103+ encipher_only=False, decipher_only=False,
104+ ),
105+ critical=True,
106+ )
107+ )
108+ return builder
109+ 
110+ 
111+def build_leaf_tbs(subject, issuer, pub_key):
112+ builder = (
113+ x509.CertificateBuilder()
114+ .subject_name(subject)
115+ .issuer_name(issuer)
116+ .public_key(pub_key)
117+ .serial_number(x509.random_serial_number())
118+ .not_valid_before(datetime.datetime(2024, 1, 1))
119+ .not_valid_after(datetime.datetime(2050, 12, 31))
120+ .add_extension(
121+ x509.BasicConstraints(ca=False, path_length=None),
122+ critical=True,
123+ )
124+ .add_extension(
125+ x509.KeyUsage(
126+ digital_signature=True, key_encipherment=True,
127+ content_commitment=False, key_agreement=False,
128+ key_cert_sign=False, crl_sign=False,
129+ data_encipherment=False, encipher_only=False, decipher_only=False,
130+ ),
131+ critical=True,
132+ )
133+ )
134+ return builder
135+ 
136+ 
137+def to_der(cert):
138+ return cert.public_bytes(serialization.Encoding.DER)
139+ 
140+ 
141+def patch_version_in_der(der_bytes, new_version):
142+ der = bytearray(der_bytes)
143+ pattern = bytes([0xA0, 0x03, 0x02, 0x01])
144+ idx = der.find(pattern)
145+ if idx < 0:
146+ raise ValueError("version field pattern not found in DER")
147+ der[idx + 4] = new_version
148+ return bytes(der)
149+ 
150+ 
151+def extract_tbs_der(cert_der):
152+ """Extract the TBSCertificate DER bytes from a Certificate SEQUENCE."""
153+ # Certificate ::= SEQUENCE { tbsCertificate, signatureAlgorithm, signatureValue }
154+ # The outer SEQUENCE tag+length is at position 0.
155+ # Inside, the first element is TBSCertificate.
156+ # Parse the outer SEQUENCE
157+ if cert_der[0] != 0x30:
158+ raise ValueError("expected SEQUENCE tag")
159+ # After outer SEQUENCE tag+length, the first child is TBS
160+ idx = 1
161+ if cert_der[1] & 0x80:
162+ idx += 1 + (cert_der[1] & 0x7F)
163+ else:
164+ idx += 1
165+ # Now idx points to the start of the first child (TBSCertificate)
166+ # Parse TBSCertificate tag+length
167+ tbs_start = idx
168+ if cert_der[idx] != 0x30:
169+ raise ValueError("expected TBS SEQUENCE tag")
170+ idx += 1
171+ if cert_der[idx] & 0x80:
172+ num_len_bytes = cert_der[idx] & 0x7F
173+ idx += 1
174+ tbs_content_len = int.from_bytes(cert_der[idx:idx + num_len_bytes], 'big')
175+ idx += num_len_bytes
176+ else:
177+ tbs_content_len = cert_der[idx]
178+ idx += 1
179+ tbs_end = idx + tbs_content_len
180+ return cert_der[tbs_start:tbs_end]
181+ 
182+ 
183+def extract_sig_alg_and_value(cert_der):
184+ """Extract signatureAlgorithm and signatureValue DER from a Certificate."""
185+ # Parse outer SEQUENCE
186+ idx = 1
187+ if cert_der[1] & 0x80:
188+ idx += 1 + (cert_der[1] & 0x7F)
189+ else:
190+ idx += 1
191+ # Skip TBSCertificate
192+ if cert_der[idx] != 0x30:
193+ raise ValueError("expected TBS SEQUENCE")
194+ idx += 1
195+ if cert_der[idx] & 0x80:
196+ num_len_bytes = cert_der[idx] & 0x7F
197+ tbs_len = int.from_bytes(cert_der[idx + 1:idx + 1 + num_len_bytes], 'big')
198+ idx += 1 + num_len_bytes + tbs_len
199+ else:
200+ tbs_len = cert_der[idx]
201+ idx += 1 + tbs_len
202+ # Now at signatureAlgorithm
203+ sig_alg_start = idx
204+ # Skip signatureAlgorithm SEQUENCE
205+ if cert_der[idx] != 0x30:
206+ raise ValueError("expected sigAlg SEQUENCE")
207+ idx += 1
208+ if cert_der[idx] & 0x80:
209+ num_len_bytes = cert_der[idx] & 0x7F
210+ sig_alg_len = int.from_bytes(cert_der[idx + 1:idx + 1 + num_len_bytes], 'big')
211+ idx += 1 + num_len_bytes + sig_alg_len
212+ else:
213+ sig_alg_len = cert_der[idx]
214+ idx += 1 + sig_alg_len
215+ sig_alg_end = idx
216+ # Now at signatureValue BIT STRING
217+ sig_val_start = idx
218+ sig_val_end = len(cert_der)
219+ return cert_der[sig_alg_start:sig_alg_end], cert_der[sig_val_start:sig_val_end]
220+ 
221+ 
222+def build_versioned_cert(tbs_builder, signing_key, version):
223+ """Build a certificate with a specific version (v1=0, v2=1) but with extensions.
224+ 
225+ 1. Sign a v3 TBS to get a valid certificate
226+ 2. Extract the TBS DER
227+ 3. Patch the version byte to the desired version
228+ 4. Re-sign the patched TBS
229+ 5. Assemble final certificate
230+ """
231+ # First, build a normal v3 cert to get the structure and signature algorithm
232+ v3_cert = tbs_builder.sign(signing_key, hashes.SHA256())
233+ v3_der = to_der(v3_cert)
234+ 
235+ # Extract TBS and patch version
236+ tbs_der = extract_tbs_der(v3_der)
237+ patched_tbs = patch_version_in_der(tbs_der, version)
238+ 
239+ # Re-sign the patched TBS
240+ sig_alg_der, _ = extract_sig_alg_and_value(v3_der)
241+ 
242+ # Compute new signature over patched TBS
243+ new_signature = signing_key.sign(
244+ patched_tbs,
245+ padding.PKCS1v15(),
246+ hashes.SHA256(),
247+ )
248+ # Wrap in BIT STRING: tag=0x03, then length, then 0x00 (unused bits), then signature bytes
249+ sig_content = b'\x00' + new_signature
250+ sig_value_der = b'\x03' + _encode_length(len(sig_content)) + sig_content
251+ 
252+ # Assemble Certificate SEQUENCE
253+ inner = patched_tbs + sig_alg_der + sig_value_der
254+ cert_der = b'\x30' + _encode_length(len(inner)) + inner
255+ return cert_der
256+ 
257+ 
258+def _encode_length(length):
259+ if length < 0x80:
260+ return bytes([length])
261+ elif length < 0x100:
262+ return bytes([0x81, length])
263+ elif length < 0x10000:
264+ return bytes([0x82, (length >> 8) & 0xFF, length & 0xFF])
265+ else:
266+ return bytes([0x83, (length >> 16) & 0xFF, (length >> 8) & 0xFF, length & 0xFF])
267+ 
268+ 
269+def save(der_bytes, filename, out_dir):
270+ path = os.path.join(out_dir, filename)
271+ with open(path, "wb") as f:
272+ f.write(der_bytes)
273+ print(f" wrote {filename} ({len(der_bytes)} bytes)")
274+ 
275+ 
276+def main():
277+ out_dir = os.path.dirname(os.path.abspath(__file__))
278+ 
279+ print("Generating keys...")
280+ root_key = gen_key()
281+ inter_key = gen_key()
282+ leaf_key = gen_key()
283+ root_b_key = gen_key()
284+ 
285+ root_name = make_root_cn()
286+ inter_name = make_inter_cn()
287+ leaf_name = make_leaf_cn()
288+ root_b_name = make_root_b_cn()
289+ 
290+ print("Generating certificates...")
291+ 
292+ # v3 root CA (trust anchor, normal)
293+ a_root = build_ca_tbs(root_name, root_name, root_key.public_key(), 2).sign(root_key, hashes.SHA256())
294+ save(to_der(a_root), "a_v3_root.der", out_dir)
295+ 
296+ # v3 intermediate CA (normal, signed by root)
297+ a_inter = build_ca_tbs(inter_name, root_name, inter_key.public_key(), 0).sign(root_key, hashes.SHA256())
298+ save(to_der(a_inter), "a_v3_inter.der", out_dir)
299+ 
300+ # v3 leaf signed by intermediate
301+ a_leaf = build_leaf_tbs(leaf_name, inter_name, leaf_key.public_key()).sign(inter_key, hashes.SHA256())
302+ save(to_der(a_leaf), "a_v3_leaf.der", out_dir)
303+ 
304+ # TC1: v1 leaf signed by root (with extensions)
305+ tbs_leaf_direct = build_leaf_tbs(leaf_name, root_name, leaf_key.public_key())
306+ save(build_versioned_cert(tbs_leaf_direct, root_key, 0x00), "a_v1_ext_leaf.der", out_dir)
307+ 
308+ # TC2: v2 leaf signed by root (with extensions)
309+ save(build_versioned_cert(tbs_leaf_direct, root_key, 0x01), "a_v2_ext_leaf.der", out_dir)
310+ 
311+ # TC3: v1 intermediate signed by root (with extensions)
312+ tbs_inter = build_ca_tbs(inter_name, root_name, inter_key.public_key(), 0)
313+ save(build_versioned_cert(tbs_inter, root_key, 0x00), "a_v1_ext_inter.der", out_dir)
314+ 
315+ # TC4: v2 intermediate signed by root (with extensions)
316+ save(build_versioned_cert(tbs_inter, root_key, 0x01), "a_v2_ext_inter.der", out_dir)
317+ 
318+ # Group b: separate root for TC5
319+ b_root = build_ca_tbs(root_b_name, root_b_name, root_b_key.public_key(), 2).sign(root_b_key, hashes.SHA256())
320+ 
321+ # TC5: v1 root (self-signed, with extensions)
322+ tbs_root_b = build_ca_tbs(root_b_name, root_b_name, root_b_key.public_key(), 2)
323+ save(build_versioned_cert(tbs_root_b, root_b_key, 0x00), "b_v1_ext_root.der", out_dir)
324+ 
325+ # v3 leaf signed by root B
326+ b_leaf = build_leaf_tbs(leaf_name, root_b_name, leaf_key.public_key()).sign(root_b_key, hashes.SHA256())
327+ save(to_der(b_leaf), "b_v3_leaf.der", out_dir)
328+ 
329+ print("Done.")
330+ 
331+ 
332+if __name__ == "__main__":
333+ main()
Mtls/cert/hitls_x509_adapt/hitls_x509_cert_chain.c+24-0
@@ -24,6 +24,8 @@
24#include "bsl_list.h"24#include "bsl_list.h"
25#include "hitls_cert.h"25#include "hitls_cert.h"
26#include "hitls_error.h"26#include "hitls_error.h"
27+#include "hitls_security.h"
28+#include "security.h"
27#include "tls.h"29#include "tls.h"
28 30 
29static int32_t BuildArrayFromList(HITLS_X509_List *list, HITLS_CERT_X509 **listArray, uint32_t *num)31static int32_t BuildArrayFromList(HITLS_X509_List *list, HITLS_CERT_X509 **listArray, uint32_t *num)
@@ -91,6 +93,21 @@ int32_t HITLS_X509_Adapt_BuildCertChain(HITLS_Config *config, HITLS_CERT_Store *
91 return ret;93 return ret;
92}94}
93 95 
96+#ifdef HITLS_TLS_FEATURE_SECURITY
97+static int32_t SetAuthLevel(HITLS_Ctx *ctx, HITLS_X509_StoreCtx *storeCtx)
98+{
99+ int32_t securityLevel = 0;
100+ int32_t ret = HITLS_CFG_GetSecurityLevel(&ctx->config.tlsConfig, &securityLevel);
101+ if (ret != HITLS_SUCCESS) {
102+ BSL_ERR_PUSH_ERROR(ret);
103+ return ret;
104+ }
105+ int32_t secBits = SECURITY_GetSecbits(securityLevel);
106+ uint32_t bits = (secBits > 0) ? (uint32_t)secBits : 0;
107+ return HITLS_X509_StoreCtxCtrl(storeCtx, HITLS_X509_STORECTX_SET_SECBITS, &bits, sizeof(bits));
108+}
109+#endif
110+ 
94int32_t HITLS_X509_Adapt_VerifyCertChain(HITLS_Ctx *ctx, HITLS_CERT_Store *store, HITLS_CERT_X509 **list, uint32_t num)111int32_t HITLS_X509_Adapt_VerifyCertChain(HITLS_Ctx *ctx, HITLS_CERT_Store *store, HITLS_CERT_X509 **list, uint32_t num)
95{112{
96 HITLS_X509_StoreCtx *storeCtx = (HITLS_X509_StoreCtx *)store;113 HITLS_X509_StoreCtx *storeCtx = (HITLS_X509_StoreCtx *)store;
@@ -106,6 +123,13 @@ int32_t HITLS_X509_Adapt_VerifyCertChain(HITLS_Ctx *ctx, HITLS_CERT_Store *store
106#endif /* HITLS_CRYPTO_SM2 */123#endif /* HITLS_CRYPTO_SM2 */
107 int32_t purpose = ctx->isClient ? HITLS_X509_VFY_PURPOSE_TLS_SERVER : HITLS_X509_VFY_PURPOSE_TLS_CLIENT;124 int32_t purpose = ctx->isClient ? HITLS_X509_VFY_PURPOSE_TLS_SERVER : HITLS_X509_VFY_PURPOSE_TLS_CLIENT;
108 HITLS_X509_StoreCtxCtrl(storeCtx, HITLS_X509_STORECTX_SET_PURPOSE, &purpose, sizeof(purpose));125 HITLS_X509_StoreCtxCtrl(storeCtx, HITLS_X509_STORECTX_SET_PURPOSE, &purpose, sizeof(purpose));
126+#ifdef HITLS_TLS_FEATURE_SECURITY
127+ ret = SetAuthLevel(ctx, storeCtx);
128+ if (ret != HITLS_SUCCESS) {
129+ BSL_ERR_PUSH_ERROR(ret);
130+ return ret;
131+ }
132+#endif
109#ifdef HITLS_TLS_CONFIG_CERT_CALLBACK133#ifdef HITLS_TLS_CONFIG_CERT_CALLBACK
110 HITLS_VerifyCb verCb = NULL;134 HITLS_VerifyCb verCb = NULL;
111 ret = HITLS_X509_StoreCtxCtrl(storeCtx, HITLS_X509_STORECTX_SET_USR_DATA, ctx, sizeof(void *));135 ret = HITLS_X509_StoreCtxCtrl(storeCtx, HITLS_X509_STORECTX_SET_USR_DATA, ctx, sizeof(void *));