From 6bfb53f084a25198835a50796eca83f463a0e7be Mon Sep 17 00:00:00 2001 From: Ruby Martin Date: Mon, 8 Jun 2026 17:22:23 -0600 Subject: [PATCH 1/4] Add pubKeySize check for SM3-with-SM2 --- wolfcrypt/src/asn.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/wolfcrypt/src/asn.c b/wolfcrypt/src/asn.c index 00be607506..664d7862f5 100644 --- a/wolfcrypt/src/asn.c +++ b/wolfcrypt/src/asn.c @@ -23380,6 +23380,10 @@ int ParseCertRelative(DecodedCert* cert, int type, int verify, void* cm, if (cert->extSubjKeyIdSet == 0 && cert->publicKey != NULL && cert->pubKeySize > 0) { if (cert->signatureOID == CTC_SM3wSM2) { + if (cert->pubKeySize < 65) { + WOLFSSL_ERROR_VERBOSE(BUFFER_E); + return BUFFER_E; + } /* TODO: GmSSL creates IDs this way but whole public key info * block should be hashed. */ ret = CalcHashId_ex(cert->publicKey + cert->pubKeySize - 65, 65, From fa5247b516914d7163e1c070d382b64c8e497c3c Mon Sep 17 00:00:00 2001 From: Ruby Martin Date: Tue, 9 Jun 2026 15:39:48 -0600 Subject: [PATCH 2/4] add regression test for sm builds --- tests/api/test_asn.c | 52 ++++++++++++++++++++++++++++++++++++++++++++ tests/api/test_asn.h | 2 ++ 2 files changed, 54 insertions(+) diff --git a/tests/api/test_asn.c b/tests/api/test_asn.c index ce4eea1487..652c3ef93f 100644 --- a/tests/api/test_asn.c +++ b/tests/api/test_asn.c @@ -1440,6 +1440,58 @@ int test_DecodeAltNames_length_underflow(void) return EXPECT_RESULT(); } +int test_ParseCert_SM3wSM2_short_pubkey(void) +{ + EXPECT_DECLS; + +#if !defined(NO_CERTS) && !defined(NO_ASN) && !defined(NO_SKID) && \ + defined(WOLFSSL_SM2) && defined(WOLFSSL_SM3) + /* Malformed cert: the SubjectPublicKeyInfo is an id-ecPublicKey key on the + * sm2p256v1 curve with only a 4-byte public key body, whole SPKI is 30 + * bytes with no subjectKeyIdentifier extension and SKID derived from the + * key. */ + static const byte sm2ShortKeyCert[] = { + 0x30, 0x81, 0xa7, + 0x30, 0x56, + 0xa0, 0x03, 0x02, 0x01, 0x02, + 0x02, 0x01, 0x01, + 0x30, 0x0a, 0x06, 0x08, + 0x2a, 0x81, 0x1c, 0xcf, 0x55, 0x01, 0x83, 0x75, + 0x30, 0x00, + 0x30, 0x1e, + 0x17, 0x0d, 0x32, 0x35, 0x31, 0x31, 0x31, 0x33, + 0x32, 0x30, 0x34, 0x31, 0x32, 0x31, 0x5a, + 0x17, 0x0d, 0x32, 0x38, 0x30, 0x38, 0x30, 0x39, + 0x32, 0x30, 0x34, 0x31, 0x32, 0x31, 0x5a, + 0x30, 0x00, + 0x30, 0x1c, + 0x30, 0x13, + 0x06, 0x07, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x02, 0x01, + 0x06, 0x08, 0x2a, 0x81, 0x1c, 0xcf, 0x55, 0x01, 0x82, 0x2d, + 0x03, 0x05, 0x00, 0x04, 0x11, 0x22, 0x33, + 0x30, 0x0a, 0x06, 0x08, + 0x2a, 0x81, 0x1c, 0xcf, 0x55, 0x01, 0x83, 0x75, + 0x03, 0x41, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + }; + DecodedCert cert; + + wc_InitDecodedCert(&cert, sm2ShortKeyCert, (word32)sizeof(sm2ShortKeyCert), + NULL); + ExpectIntEQ(wc_ParseCert(&cert, CERT_TYPE, NO_VERIFY, NULL), + WC_NO_ERR_TRACE(BUFFER_E)); + wc_FreeDecodedCert(&cert); +#endif + return EXPECT_RESULT(); +} + int test_SerialNumber0_RootCA(void) { EXPECT_DECLS; diff --git a/tests/api/test_asn.h b/tests/api/test_asn.h index 2654e3e858..a0c72b2517 100644 --- a/tests/api/test_asn.h +++ b/tests/api/test_asn.h @@ -35,6 +35,7 @@ int test_wolfssl_local_MatchUriNameConstraint(void); int test_wc_DecodeRsaPssParams(void); int test_SerialNumber0_RootCA(void); int test_DecodeAltNames_length_underflow(void); +int test_ParseCert_SM3wSM2_short_pubkey(void); int test_wc_DecodeObjectId(void); int test_ToTraditional_ex_handcrafted(void); int test_ToTraditional_ex_roundtrip(void); @@ -53,6 +54,7 @@ int test_ToTraditional_ex_mldsa_bad_params(void); TEST_DECL_GROUP("asn", test_wc_DecodeRsaPssParams), \ TEST_DECL_GROUP("asn", test_SerialNumber0_RootCA), \ TEST_DECL_GROUP("asn", test_DecodeAltNames_length_underflow), \ + TEST_DECL_GROUP("asn", test_ParseCert_SM3wSM2_short_pubkey), \ TEST_DECL_GROUP("asn", test_wc_DecodeObjectId), \ TEST_DECL_GROUP("asn", test_ToTraditional_ex_handcrafted), \ TEST_DECL_GROUP("asn", test_ToTraditional_ex_roundtrip), \ From 1786cebf8c84861ea274642203b9d29bd1d52b52 Mon Sep 17 00:00:00 2001 From: Ruby Martin Date: Tue, 9 Jun 2026 10:43:33 -0600 Subject: [PATCH 3/4] add negative value check after wc_HashGetDigestSize --- wolfcrypt/src/asn.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/wolfcrypt/src/asn.c b/wolfcrypt/src/asn.c index 664d7862f5..910a318a5d 100644 --- a/wolfcrypt/src/asn.c +++ b/wolfcrypt/src/asn.c @@ -30236,11 +30236,16 @@ static int SetAuthKeyIdFromDcert(Cert* cert, DecodedCert* decoded) #if defined(WOLFSSL_SM2) && defined(WOLFSSL_SM3) cert->akidSz = wc_HashGetDigestSize(wc_HashTypeConvert(HashIdAlg( cert->sigType))); + if (cert->akidSz <= 0) { + ret = HASH_TYPE_E; + } #else cert->akidSz = KEYID_SIZE; #endif - /* Put the SKID of CA to AKID of certificate */ - XMEMCPY(cert->akid, decoded->extSubjKeyId, (size_t)cert->akidSz); + if (ret == 0) { + /* Put the SKID of CA to AKID of certificate */ + XMEMCPY(cert->akid, decoded->extSubjKeyId, (size_t)cert->akidSz); + } } return ret; From b167c2687e55855687de2e7fc926efa13ef3fda2 Mon Sep 17 00:00:00 2001 From: Ruby Martin Date: Tue, 9 Jun 2026 11:26:02 -0600 Subject: [PATCH 4/4] verify i >= 0 before continuing loop. clears coverity false positive --- wolfcrypt/src/asn.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wolfcrypt/src/asn.c b/wolfcrypt/src/asn.c index 910a318a5d..d7f6ad6c93 100644 --- a/wolfcrypt/src/asn.c +++ b/wolfcrypt/src/asn.c @@ -27156,7 +27156,7 @@ static void SetRdnItems(ASNItem* namesASN, ASNSetData* dataASN, const byte* oid, static int FindMultiAttrib(CertName* name, int id, int* idx) { int i; - for (i = *idx + 1; i < CTC_MAX_ATTRIB; i++) { + for (i = *idx + 1; i >= 0 && i < CTC_MAX_ATTRIB; i++) { if (name->name[i].sz > 0 && name->name[i].id == id) { break; }