@@ -20097,6 +20097,262 @@ static int test_MakeCertWithCaFalse(void)
2009720097 return EXPECT_RESULT();
2009820098}
2009920099
20100+ /* Mock callback for testing wc_SignCert_cb */
20101+ #if defined(WOLFSSL_CERT_SIGN_CB) && (defined(WOLFSSL_CERT_GEN) || defined(WOLFSSL_CERT_REQ))
20102+ /* Context structure for mock signing callback */
20103+ typedef struct {
20104+ void* key; /* Pointer to RSA or ECC key */
20105+ WC_RNG* rng; /* Random number generator (required for ECC) */
20106+ } MockSignCtx;
20107+
20108+ static int mockSignCb(const byte* in, word32 inLen, byte* out, word32* outLen,
20109+ int sigAlgo, int keyType, void* ctx)
20110+ {
20111+ int ret = 0;
20112+ MockSignCtx* signCtx = (MockSignCtx*)ctx;
20113+
20114+ if (signCtx == NULL || signCtx->key == NULL || in == NULL ||
20115+ out == NULL || outLen == NULL) {
20116+ return BAD_FUNC_ARG;
20117+ }
20118+
20119+ (void)sigAlgo;
20120+
20121+ #ifndef NO_RSA
20122+ if (keyType == RSA_TYPE) {
20123+ RsaKey* rsaKey = (RsaKey*)signCtx->key;
20124+ word32 outSz = *outLen;
20125+
20126+ /* For RSA, input is DER-encoded digest (DigestInfo structure) */
20127+ ret = wc_RsaSSL_Sign(in, inLen, out, outSz, rsaKey, signCtx->rng);
20128+ if (ret > 0) {
20129+ *outLen = (word32)ret;
20130+ ret = 0;
20131+ }
20132+ }
20133+ else
20134+ #endif
20135+ #ifdef HAVE_ECC
20136+ if (keyType == ECC_TYPE) {
20137+ ecc_key* eccKey = (ecc_key*)signCtx->key;
20138+ word32 outSz = *outLen;
20139+
20140+ /* For ECC, input is raw hash, sign it (RNG required for ECDSA k value) */
20141+ ret = wc_ecc_sign_hash(in, inLen, out, &outSz, signCtx->rng, eccKey);
20142+ if (ret == 0) {
20143+ *outLen = outSz;
20144+ }
20145+ }
20146+ else
20147+ #endif
20148+ {
20149+ ret = BAD_FUNC_ARG;
20150+ }
20151+
20152+ return ret;
20153+ }
20154+
20155+ /* Mock callback that always returns an error for testing */
20156+ static int mockSignCbError(const byte* in, word32 inLen, byte* out,
20157+ word32* outLen, int sigAlgo, int keyType, void* ctx)
20158+ {
20159+ (void)in;
20160+ (void)inLen;
20161+ (void)out;
20162+ (void)outLen;
20163+ (void)sigAlgo;
20164+ (void)keyType;
20165+ (void)ctx;
20166+ return BAD_STATE_E; /* Return an error */
20167+ }
20168+ #endif
20169+
20170+ #ifdef WOLFSSL_CERT_SIGN_CB
20171+ static int test_wc_SignCert_cb(void)
20172+ {
20173+ EXPECT_DECLS;
20174+ #if defined(WOLFSSL_CERT_GEN) && !defined(NO_ASN_TIME)
20175+
20176+ #ifdef HAVE_ECC
20177+ /* Test with ECC key */
20178+ {
20179+ Cert cert;
20180+ byte der[FOURK_BUF];
20181+ int derSize = 0;
20182+ WC_RNG rng;
20183+ ecc_key key;
20184+ MockSignCtx signCtx;
20185+ DecodedCert decodedCert;
20186+ int ret;
20187+
20188+ XMEMSET(&rng, 0, sizeof(WC_RNG));
20189+ XMEMSET(&key, 0, sizeof(ecc_key));
20190+ XMEMSET(&cert, 0, sizeof(Cert));
20191+ XMEMSET(&signCtx, 0, sizeof(MockSignCtx));
20192+ XMEMSET(&decodedCert, 0, sizeof(DecodedCert));
20193+
20194+ ExpectIntEQ(wc_InitRng(&rng), 0);
20195+ ExpectIntEQ(wc_ecc_init(&key), 0);
20196+ ExpectIntEQ(wc_ecc_make_key(&rng, 32, &key), 0);
20197+ ExpectIntEQ(wc_InitCert(&cert), 0);
20198+
20199+ (void)XSTRNCPY(cert.subject.country, "US", CTC_NAME_SIZE);
20200+ (void)XSTRNCPY(cert.subject.state, "state", CTC_NAME_SIZE);
20201+ (void)XSTRNCPY(cert.subject.locality, "locality", CTC_NAME_SIZE);
20202+ (void)XSTRNCPY(cert.subject.org, "org", CTC_NAME_SIZE);
20203+ (void)XSTRNCPY(cert.subject.unit, "unit", CTC_NAME_SIZE);
20204+ (void)XSTRNCPY(cert.subject.commonName, "www.example.com",
20205+ CTC_NAME_SIZE);
20206+ (void)XSTRNCPY(cert.subject.email, "test@example.com", CTC_NAME_SIZE);
20207+
20208+ cert.selfSigned = 1;
20209+ cert.isCA = 0;
20210+ cert.sigType = CTC_SHA256wECDSA;
20211+
20212+ /* Make cert body */
20213+ ExpectIntGT(wc_MakeCert(&cert, der, FOURK_BUF, NULL, &key, &rng), 0);
20214+
20215+ /* Setup signing context with key and RNG */
20216+ signCtx.key = &key;
20217+ signCtx.rng = &rng;
20218+
20219+ /* Sign using callback API */
20220+ ExpectIntGT(derSize = wc_SignCert_cb(cert.bodySz, cert.sigType, der,
20221+ FOURK_BUF, ECC_TYPE, mockSignCb, &signCtx, &rng), 0);
20222+
20223+ /* Verify the certificate was created properly */
20224+ ExpectIntGT(derSize, 0);
20225+
20226+ /* Parse the certificate and verify it's well-formed */
20227+ if (EXPECT_SUCCESS()) {
20228+ wc_InitDecodedCert(&decodedCert, der, (word32)derSize, NULL);
20229+ ExpectIntEQ(wc_ParseCert(&decodedCert, CERT_TYPE, NO_VERIFY, NULL),
20230+ 0);
20231+ /* Verify signature algorithm matches what we set */
20232+ ExpectIntEQ(decodedCert.signatureOID, CTC_SHA256wECDSA);
20233+ wc_FreeDecodedCert(&decodedCert);
20234+ }
20235+
20236+ /* Test error cases */
20237+ /* NULL callback */
20238+ ExpectIntEQ(wc_SignCert_cb(cert.bodySz, cert.sigType, der,
20239+ FOURK_BUF, ECC_TYPE, NULL, &signCtx, &rng), BAD_FUNC_ARG);
20240+ /* NULL buffer */
20241+ ExpectIntEQ(wc_SignCert_cb(cert.bodySz, cert.sigType, NULL,
20242+ FOURK_BUF, ECC_TYPE, mockSignCb, &signCtx, &rng), BAD_FUNC_ARG);
20243+ /* Zero buffer size */
20244+ ExpectIntEQ(wc_SignCert_cb(cert.bodySz, cert.sigType, der,
20245+ 0, ECC_TYPE, mockSignCb, &signCtx, &rng), BAD_FUNC_ARG);
20246+ /* Negative requestSz - should return the negative value */
20247+ ExpectIntLT(wc_SignCert_cb(-1, cert.sigType, der,
20248+ FOURK_BUF, ECC_TYPE, mockSignCb, &signCtx, &rng), 0);
20249+ /* Callback returning error */
20250+ ExpectIntEQ(wc_SignCert_cb(cert.bodySz, cert.sigType, der,
20251+ FOURK_BUF, ECC_TYPE, mockSignCbError, &signCtx, &rng), BAD_STATE_E);
20252+ #ifndef NO_RSA
20253+ /* Invalid keyType for ECC signature */
20254+ ExpectIntEQ(wc_SignCert_cb(cert.bodySz, cert.sigType, der,
20255+ FOURK_BUF, ED25519_TYPE, mockSignCb, &signCtx, &rng), BAD_FUNC_ARG);
20256+ #endif
20257+
20258+ ret = wc_ecc_free(&key);
20259+ ExpectIntEQ(ret, 0);
20260+ ret = wc_FreeRng(&rng);
20261+ ExpectIntEQ(ret, 0);
20262+ }
20263+ #endif /* HAVE_ECC */
20264+
20265+ #if !defined(NO_RSA) && defined(WOLFSSL_KEY_GEN)
20266+ /* Test with RSA key */
20267+ {
20268+ Cert cert;
20269+ byte der[FOURK_BUF];
20270+ int derSize = 0;
20271+ WC_RNG rng;
20272+ RsaKey key;
20273+ MockSignCtx signCtx;
20274+ DecodedCert decodedCert;
20275+ int ret;
20276+
20277+ XMEMSET(&rng, 0, sizeof(WC_RNG));
20278+ XMEMSET(&key, 0, sizeof(RsaKey));
20279+ XMEMSET(&cert, 0, sizeof(Cert));
20280+ XMEMSET(&signCtx, 0, sizeof(MockSignCtx));
20281+ XMEMSET(&decodedCert, 0, sizeof(DecodedCert));
20282+
20283+ ExpectIntEQ(wc_InitRng(&rng), 0);
20284+ ExpectIntEQ(wc_InitRsaKey(&key, NULL), 0);
20285+ ExpectIntEQ(wc_MakeRsaKey(&key, 2048, WC_RSA_EXPONENT, &rng), 0);
20286+ ExpectIntEQ(wc_InitCert(&cert), 0);
20287+
20288+ (void)XSTRNCPY(cert.subject.country, "US", CTC_NAME_SIZE);
20289+ (void)XSTRNCPY(cert.subject.state, "state", CTC_NAME_SIZE);
20290+ (void)XSTRNCPY(cert.subject.locality, "locality", CTC_NAME_SIZE);
20291+ (void)XSTRNCPY(cert.subject.org, "org", CTC_NAME_SIZE);
20292+ (void)XSTRNCPY(cert.subject.unit, "unit", CTC_NAME_SIZE);
20293+ (void)XSTRNCPY(cert.subject.commonName, "www.example.com",
20294+ CTC_NAME_SIZE);
20295+ (void)XSTRNCPY(cert.subject.email, "test@example.com", CTC_NAME_SIZE);
20296+
20297+ cert.selfSigned = 1;
20298+ cert.isCA = 0;
20299+ cert.sigType = CTC_SHA256wRSA;
20300+
20301+ /* Make cert body */
20302+ ExpectIntGT(wc_MakeCert(&cert, der, FOURK_BUF, &key, NULL, &rng), 0);
20303+
20304+ /* Setup signing context with key and RNG */
20305+ signCtx.key = &key;
20306+ signCtx.rng = &rng;
20307+
20308+ /* Sign using callback API with RSA */
20309+ ExpectIntGT(derSize = wc_SignCert_cb(cert.bodySz, cert.sigType, der,
20310+ FOURK_BUF, RSA_TYPE, mockSignCb, &signCtx, &rng), 0);
20311+
20312+ /* Verify the certificate was created properly */
20313+ ExpectIntGT(derSize, 0);
20314+
20315+ /* Parse the certificate and verify it's well-formed */
20316+ if (EXPECT_SUCCESS()) {
20317+ wc_InitDecodedCert(&decodedCert, der, (word32)derSize, NULL);
20318+ ExpectIntEQ(wc_ParseCert(&decodedCert, CERT_TYPE, NO_VERIFY, NULL),
20319+ 0);
20320+ /* Verify signature algorithm matches what we set */
20321+ ExpectIntEQ(decodedCert.signatureOID, CTC_SHA256wRSA);
20322+ wc_FreeDecodedCert(&decodedCert);
20323+ }
20324+
20325+ /* Test error cases */
20326+ /* NULL callback */
20327+ ExpectIntEQ(wc_SignCert_cb(cert.bodySz, cert.sigType, der,
20328+ FOURK_BUF, RSA_TYPE, NULL, &signCtx, &rng), BAD_FUNC_ARG);
20329+ /* NULL buffer */
20330+ ExpectIntEQ(wc_SignCert_cb(cert.bodySz, cert.sigType, NULL,
20331+ FOURK_BUF, RSA_TYPE, mockSignCb, &signCtx, &rng), BAD_FUNC_ARG);
20332+ /* Zero buffer size */
20333+ ExpectIntEQ(wc_SignCert_cb(cert.bodySz, cert.sigType, der,
20334+ 0, RSA_TYPE, mockSignCb, &signCtx, &rng), BAD_FUNC_ARG);
20335+ /* Callback returning error */
20336+ ExpectIntEQ(wc_SignCert_cb(cert.bodySz, cert.sigType, der,
20337+ FOURK_BUF, RSA_TYPE, mockSignCbError, &signCtx, &rng), BAD_STATE_E);
20338+ #ifdef HAVE_ECC
20339+ /* Invalid keyType */
20340+ ExpectIntEQ(wc_SignCert_cb(cert.bodySz, cert.sigType, der,
20341+ FOURK_BUF, ED448_TYPE, mockSignCb, &signCtx, &rng), BAD_FUNC_ARG);
20342+ #endif
20343+
20344+ ret = wc_FreeRsaKey(&key);
20345+ ExpectIntEQ(ret, 0);
20346+ ret = wc_FreeRng(&rng);
20347+ ExpectIntEQ(ret, 0);
20348+ }
20349+ #endif /* !NO_RSA && WOLFSSL_KEY_GEN */
20350+
20351+ #endif /* WOLFSSL_CERT_GEN && !NO_ASN_TIME */
20352+ return EXPECT_RESULT();
20353+ }
20354+ #endif /* WOLFSSL_CERT_SIGN_CB */
20355+
2010020356static int test_ERR_load_crypto_strings(void)
2010120357{
2010220358#if defined(OPENSSL_ALL)
@@ -31577,6 +31833,9 @@ TEST_CASE testCases[] = {
3157731833 TEST_DECL(test_MakeCertWithPathLen),
3157831834 TEST_DECL(test_MakeCertWith0Ser),
3157931835 TEST_DECL(test_MakeCertWithCaFalse),
31836+ #ifdef WOLFSSL_CERT_SIGN_CB
31837+ TEST_DECL(test_wc_SignCert_cb),
31838+ #endif
3158031839 TEST_DECL(test_wc_SetKeyUsage),
3158131840 TEST_DECL(test_wc_SetAuthKeyIdFromPublicKey_ex),
3158231841 TEST_DECL(test_wc_SetSubjectBuffer),
0 commit comments