diff --git a/tests/api/test_asn.c b/tests/api/test_asn.c index 19906ff02b..63cbfd365d 100644 --- a/tests/api/test_asn.c +++ b/tests/api/test_asn.c @@ -1495,6 +1495,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), \ diff --git a/wolfcrypt/src/asn.c b/wolfcrypt/src/asn.c index 1e97e72fe3..05155e02a4 100644 --- a/wolfcrypt/src/asn.c +++ b/wolfcrypt/src/asn.c @@ -23490,6 +23490,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, @@ -27262,7 +27266,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; } @@ -30806,11 +30810,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;