Skip to content

Commit cb2b7ad

Browse files
committed
Address PR feedback: move doxygen to proper location and add RSA test coverage
1 parent 8b5bd3b commit cb2b7ad

5 files changed

Lines changed: 170 additions & 100 deletions

File tree

doc/dox_comments/header_files/asn.h

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -237,3 +237,62 @@ word32 SetAlgoID(int algoOID, byte* output, int type, int curveSz);
237237
*/
238238
int wc_DhPublicKeyDecode(const byte* input, word32* inOutIdx, DhKey* key,
239239
word32 inSz);
240+
241+
/*!
242+
\ingroup CertManager
243+
\brief Sign a certificate or CSR using a callback function.
244+
245+
This function signs a certificate or Certificate Signing Request (CSR)
246+
using a user-provided signing callback. This allows external signing
247+
implementations (e.g., TPM, HSM) without requiring the crypto callback
248+
infrastructure, making it suitable for FIPS-compliant applications.
249+
250+
The function performs the following:
251+
1. Hashes the certificate/CSR body according to the signature algorithm
252+
2. Encodes the hash (RSA) or prepares it for signing (ECC)
253+
3. Calls the user-provided callback to perform the actual signing
254+
4. Encodes the signature into the certificate/CSR DER structure
255+
256+
\param requestSz Size of the certificate body to sign (from Cert.bodySz).
257+
\param sType Signature algorithm type (e.g., CTC_SHA256wRSA,
258+
CTC_SHA256wECDSA).
259+
\param buf Buffer containing the certificate/CSR DER data to sign.
260+
\param buffSz Total size of the buffer (must be large enough for signature).
261+
\param keyType Type of key used for signing (RSA_TYPE, ECC_TYPE, etc.).
262+
\param signCb User-provided signing callback function.
263+
\param signCtx Context pointer passed to the signing callback.
264+
\param rng Random number generator (may be NULL if not needed).
265+
266+
\return Size of the signed certificate/CSR on success.
267+
\return BAD_FUNC_ARG if signCb is NULL or other parameters are invalid.
268+
\return BUFFER_E if the buffer is too small for the signed certificate.
269+
\return MEMORY_E if memory allocation fails.
270+
\return Negative error code on other failures.
271+
272+
_Example_
273+
\code
274+
Cert cert;
275+
byte derBuf[4096];
276+
int derSz;
277+
MySignCtx myCtx;
278+
279+
wc_InitCert(&cert);
280+
281+
derSz = wc_MakeCert(&cert, derBuf, sizeof(derBuf), NULL, NULL, &rng);
282+
283+
derSz = wc_SignCert_cb(cert.bodySz, cert.sigType, derBuf, sizeof(derBuf),
284+
RSA_TYPE, mySignCallback, &myCtx, &rng);
285+
if (derSz > 0) {
286+
printf("Signed certificate is %d bytes\n", derSz);
287+
}
288+
\endcode
289+
290+
\sa wc_SignCertCb
291+
\sa wc_SignCert
292+
\sa wc_SignCert_ex
293+
\sa wc_MakeCert
294+
\sa wc_MakeCertReq
295+
*/
296+
int wc_SignCert_cb(int requestSz, int sType, byte* buf, word32 buffSz,
297+
int keyType, wc_SignCertCb signCb, void* signCtx,
298+
WC_RNG* rng);

tests/api.c

Lines changed: 111 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -20047,61 +20047,127 @@ static int mockSignCb(const byte* in, word32 inLen, byte* out, word32* outLen,
2004720047
static int test_wc_SignCert_cb(void)
2004820048
{
2004920049
EXPECT_DECLS;
20050-
#if defined(WOLFSSL_CERT_GEN) && defined(HAVE_ECC) && !defined(NO_ASN_TIME)
20051-
Cert cert;
20052-
byte der[FOURK_BUF];
20053-
int derSize = 0;
20054-
WC_RNG rng;
20055-
ecc_key key;
20056-
MockSignCtx signCtx;
20057-
int ret;
20050+
#if defined(WOLFSSL_CERT_GEN) && !defined(NO_ASN_TIME)
2005820051

20059-
XMEMSET(&rng, 0, sizeof(WC_RNG));
20060-
XMEMSET(&key, 0, sizeof(ecc_key));
20061-
XMEMSET(&cert, 0, sizeof(Cert));
20062-
XMEMSET(&signCtx, 0, sizeof(MockSignCtx));
20052+
#ifdef HAVE_ECC
20053+
/* Test with ECC key */
20054+
{
20055+
Cert cert;
20056+
byte der[FOURK_BUF];
20057+
int derSize = 0;
20058+
WC_RNG rng;
20059+
ecc_key key;
20060+
MockSignCtx signCtx;
20061+
int ret;
2006320062

20064-
ExpectIntEQ(wc_InitRng(&rng), 0);
20065-
ExpectIntEQ(wc_ecc_init(&key), 0);
20066-
ExpectIntEQ(wc_ecc_make_key(&rng, 32, &key), 0);
20067-
ExpectIntEQ(wc_InitCert(&cert), 0);
20063+
XMEMSET(&rng, 0, sizeof(WC_RNG));
20064+
XMEMSET(&key, 0, sizeof(ecc_key));
20065+
XMEMSET(&cert, 0, sizeof(Cert));
20066+
XMEMSET(&signCtx, 0, sizeof(MockSignCtx));
2006820067

20069-
(void)XSTRNCPY(cert.subject.country, "US", CTC_NAME_SIZE);
20070-
(void)XSTRNCPY(cert.subject.state, "state", CTC_NAME_SIZE);
20071-
(void)XSTRNCPY(cert.subject.locality, "locality", CTC_NAME_SIZE);
20072-
(void)XSTRNCPY(cert.subject.org, "org", CTC_NAME_SIZE);
20073-
(void)XSTRNCPY(cert.subject.unit, "unit", CTC_NAME_SIZE);
20074-
(void)XSTRNCPY(cert.subject.commonName, "www.example.com",
20075-
CTC_NAME_SIZE);
20076-
(void)XSTRNCPY(cert.subject.email, "test@example.com", CTC_NAME_SIZE);
20068+
ExpectIntEQ(wc_InitRng(&rng), 0);
20069+
ExpectIntEQ(wc_ecc_init(&key), 0);
20070+
ExpectIntEQ(wc_ecc_make_key(&rng, 32, &key), 0);
20071+
ExpectIntEQ(wc_InitCert(&cert), 0);
2007720072

20078-
cert.selfSigned = 1;
20079-
cert.isCA = 0;
20080-
cert.sigType = CTC_SHA256wECDSA;
20073+
(void)XSTRNCPY(cert.subject.country, "US", CTC_NAME_SIZE);
20074+
(void)XSTRNCPY(cert.subject.state, "state", CTC_NAME_SIZE);
20075+
(void)XSTRNCPY(cert.subject.locality, "locality", CTC_NAME_SIZE);
20076+
(void)XSTRNCPY(cert.subject.org, "org", CTC_NAME_SIZE);
20077+
(void)XSTRNCPY(cert.subject.unit, "unit", CTC_NAME_SIZE);
20078+
(void)XSTRNCPY(cert.subject.commonName, "www.example.com",
20079+
CTC_NAME_SIZE);
20080+
(void)XSTRNCPY(cert.subject.email, "test@example.com", CTC_NAME_SIZE);
2008120081

20082-
/* Make cert body */
20083-
ExpectIntGT(wc_MakeCert(&cert, der, FOURK_BUF, NULL, &key, &rng), 0);
20082+
cert.selfSigned = 1;
20083+
cert.isCA = 0;
20084+
cert.sigType = CTC_SHA256wECDSA;
2008420085

20085-
/* Setup signing context with key and RNG */
20086-
signCtx.key = &key;
20087-
signCtx.rng = &rng;
20086+
/* Make cert body */
20087+
ExpectIntGT(wc_MakeCert(&cert, der, FOURK_BUF, NULL, &key, &rng), 0);
2008820088

20089-
/* Sign using callback API */
20090-
ExpectIntGT(derSize = wc_SignCert_cb(cert.bodySz, cert.sigType, der,
20091-
FOURK_BUF, ECC_TYPE, mockSignCb, &signCtx, &rng), 0);
20089+
/* Setup signing context with key and RNG */
20090+
signCtx.key = &key;
20091+
signCtx.rng = &rng;
2009220092

20093-
/* Verify the certificate was created properly */
20094-
ExpectIntGT(derSize, 0);
20093+
/* Sign using callback API */
20094+
ExpectIntGT(derSize = wc_SignCert_cb(cert.bodySz, cert.sigType, der,
20095+
FOURK_BUF, ECC_TYPE, mockSignCb, &signCtx, &rng), 0);
2009520096

20096-
/* Test error cases */
20097-
ExpectIntEQ(wc_SignCert_cb(cert.bodySz, cert.sigType, der,
20098-
FOURK_BUF, ECC_TYPE, NULL, &signCtx, &rng), BAD_FUNC_ARG);
20097+
/* Verify the certificate was created properly */
20098+
ExpectIntGT(derSize, 0);
2009920099

20100-
ret = wc_ecc_free(&key);
20101-
ExpectIntEQ(ret, 0);
20102-
ret = wc_FreeRng(&rng);
20103-
ExpectIntEQ(ret, 0);
20104-
#endif
20100+
/* Test error cases */
20101+
ExpectIntEQ(wc_SignCert_cb(cert.bodySz, cert.sigType, der,
20102+
FOURK_BUF, ECC_TYPE, NULL, &signCtx, &rng), BAD_FUNC_ARG);
20103+
20104+
ret = wc_ecc_free(&key);
20105+
ExpectIntEQ(ret, 0);
20106+
ret = wc_FreeRng(&rng);
20107+
ExpectIntEQ(ret, 0);
20108+
}
20109+
#endif /* HAVE_ECC */
20110+
20111+
#if !defined(NO_RSA) && defined(WOLFSSL_KEY_GEN)
20112+
/* Test with RSA key */
20113+
{
20114+
Cert cert;
20115+
byte der[FOURK_BUF];
20116+
int derSize = 0;
20117+
WC_RNG rng;
20118+
RsaKey key;
20119+
MockSignCtx signCtx;
20120+
int ret;
20121+
20122+
XMEMSET(&rng, 0, sizeof(WC_RNG));
20123+
XMEMSET(&key, 0, sizeof(RsaKey));
20124+
XMEMSET(&cert, 0, sizeof(Cert));
20125+
XMEMSET(&signCtx, 0, sizeof(MockSignCtx));
20126+
20127+
ExpectIntEQ(wc_InitRng(&rng), 0);
20128+
ExpectIntEQ(wc_InitRsaKey(&key, NULL), 0);
20129+
ExpectIntEQ(wc_MakeRsaKey(&key, 2048, WC_RSA_EXPONENT, &rng), 0);
20130+
ExpectIntEQ(wc_InitCert(&cert), 0);
20131+
20132+
(void)XSTRNCPY(cert.subject.country, "US", CTC_NAME_SIZE);
20133+
(void)XSTRNCPY(cert.subject.state, "state", CTC_NAME_SIZE);
20134+
(void)XSTRNCPY(cert.subject.locality, "locality", CTC_NAME_SIZE);
20135+
(void)XSTRNCPY(cert.subject.org, "org", CTC_NAME_SIZE);
20136+
(void)XSTRNCPY(cert.subject.unit, "unit", CTC_NAME_SIZE);
20137+
(void)XSTRNCPY(cert.subject.commonName, "www.example.com",
20138+
CTC_NAME_SIZE);
20139+
(void)XSTRNCPY(cert.subject.email, "test@example.com", CTC_NAME_SIZE);
20140+
20141+
cert.selfSigned = 1;
20142+
cert.isCA = 0;
20143+
cert.sigType = CTC_SHA256wRSA;
20144+
20145+
/* Make cert body */
20146+
ExpectIntGT(wc_MakeCert(&cert, der, FOURK_BUF, &key, NULL, &rng), 0);
20147+
20148+
/* Setup signing context with key and RNG */
20149+
signCtx.key = &key;
20150+
signCtx.rng = &rng;
20151+
20152+
/* Sign using callback API with RSA */
20153+
ExpectIntGT(derSize = wc_SignCert_cb(cert.bodySz, cert.sigType, der,
20154+
FOURK_BUF, RSA_TYPE, mockSignCb, &signCtx, &rng), 0);
20155+
20156+
/* Verify the certificate was created properly */
20157+
ExpectIntGT(derSize, 0);
20158+
20159+
/* Test error case - NULL callback */
20160+
ExpectIntEQ(wc_SignCert_cb(cert.bodySz, cert.sigType, der,
20161+
FOURK_BUF, RSA_TYPE, NULL, &signCtx, &rng), BAD_FUNC_ARG);
20162+
20163+
ret = wc_FreeRsaKey(&key);
20164+
ExpectIntEQ(ret, 0);
20165+
ret = wc_FreeRng(&rng);
20166+
ExpectIntEQ(ret, 0);
20167+
}
20168+
#endif /* !NO_RSA && WOLFSSL_KEY_GEN */
20169+
20170+
#endif /* WOLFSSL_CERT_GEN && !NO_ASN_TIME */
2010520171
return EXPECT_RESULT();
2010620172
}
2010720173
#endif /* WOLFSSL_CERT_SIGN_CB */

tests/test_cert_sign_cb_no_malloc.c

Whitespace-only changes.

tests/test_cert_sign_cb_no_malloc_simple.c

Whitespace-only changes.

wolfssl/wolfcrypt/asn_public.h

Lines changed: 0 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -551,61 +551,6 @@ WOLFSSL_API int wc_SignCert_ex(int requestSz, int sType, byte* buf,
551551
WC_RNG* rng);
552552
WOLFSSL_API int wc_SignCert(int requestSz, int sType, byte* buf, word32 buffSz,
553553
RsaKey* rsaKey, ecc_key* eccKey, WC_RNG* rng);
554-
/*!
555-
\ingroup CertManager
556-
\brief Sign a certificate or CSR using a callback function.
557-
558-
This function signs a certificate or Certificate Signing Request (CSR)
559-
using a user-provided signing callback. This allows external signing
560-
implementations (e.g., TPM, HSM) without requiring the crypto callback
561-
infrastructure, making it suitable for FIPS-compliant applications.
562-
563-
The function performs the following:
564-
1. Hashes the certificate/CSR body according to the signature algorithm
565-
2. Encodes the hash (RSA) or prepares it for signing (ECC)
566-
3. Calls the user-provided callback to perform the actual signing
567-
4. Encodes the signature into the certificate/CSR DER structure
568-
569-
\param requestSz Size of the certificate body to sign (from Cert.bodySz).
570-
\param sType Signature algorithm type (e.g., CTC_SHA256wRSA,
571-
CTC_SHA256wECDSA).
572-
\param buf Buffer containing the certificate/CSR DER data to sign.
573-
\param buffSz Total size of the buffer (must be large enough for signature).
574-
\param keyType Type of key used for signing (RSA_TYPE, ECC_TYPE, etc.).
575-
\param signCb User-provided signing callback function.
576-
\param signCtx Context pointer passed to the signing callback.
577-
\param rng Random number generator (may be NULL if not needed).
578-
579-
\return Size of the signed certificate/CSR on success.
580-
\return BAD_FUNC_ARG if signCb is NULL or other parameters are invalid.
581-
\return BUFFER_E if the buffer is too small for the signed certificate.
582-
\return MEMORY_E if memory allocation fails.
583-
\return Negative error code on other failures.
584-
585-
\sa wc_SignCertCb
586-
\sa wc_SignCert
587-
\sa wc_SignCert_ex
588-
\sa wc_MakeCert
589-
\sa wc_MakeCertReq
590-
591-
_Example_
592-
\code
593-
Cert cert;
594-
byte derBuf[4096];
595-
int derSz;
596-
MySignCtx myCtx;
597-
598-
wc_InitCert(&cert);
599-
600-
derSz = wc_MakeCert(&cert, derBuf, sizeof(derBuf), NULL, NULL, &rng);
601-
602-
derSz = wc_SignCert_cb(cert.bodySz, cert.sigType, derBuf, sizeof(derBuf),
603-
RSA_TYPE, mySignCallback, &myCtx, &rng);
604-
if (derSz > 0) {
605-
printf("Signed certificate is %d bytes\n", derSz);
606-
}
607-
\endcode
608-
*/
609554
#ifdef WOLFSSL_CERT_SIGN_CB
610555
WOLFSSL_API int wc_SignCert_cb(int requestSz, int sType, byte* buf,
611556
word32 buffSz, int keyType,

0 commit comments

Comments
 (0)