Address PR feedback: move doxygen to proper location and add RSA test coverage

This commit is contained in:
jackctj117
2026-02-04 10:45:38 -07:00
parent 8b5bd3b3b1
commit cb2b7adfcc
5 changed files with 170 additions and 100 deletions
+59
View File
@@ -237,3 +237,62 @@ word32 SetAlgoID(int algoOID, byte* output, int type, int curveSz);
*/
int wc_DhPublicKeyDecode(const byte* input, word32* inOutIdx, DhKey* key,
word32 inSz);
/*!
\ingroup CertManager
\brief Sign a certificate or CSR using a callback function.
This function signs a certificate or Certificate Signing Request (CSR)
using a user-provided signing callback. This allows external signing
implementations (e.g., TPM, HSM) without requiring the crypto callback
infrastructure, making it suitable for FIPS-compliant applications.
The function performs the following:
1. Hashes the certificate/CSR body according to the signature algorithm
2. Encodes the hash (RSA) or prepares it for signing (ECC)
3. Calls the user-provided callback to perform the actual signing
4. Encodes the signature into the certificate/CSR DER structure
\param requestSz Size of the certificate body to sign (from Cert.bodySz).
\param sType Signature algorithm type (e.g., CTC_SHA256wRSA,
CTC_SHA256wECDSA).
\param buf Buffer containing the certificate/CSR DER data to sign.
\param buffSz Total size of the buffer (must be large enough for signature).
\param keyType Type of key used for signing (RSA_TYPE, ECC_TYPE, etc.).
\param signCb User-provided signing callback function.
\param signCtx Context pointer passed to the signing callback.
\param rng Random number generator (may be NULL if not needed).
\return Size of the signed certificate/CSR on success.
\return BAD_FUNC_ARG if signCb is NULL or other parameters are invalid.
\return BUFFER_E if the buffer is too small for the signed certificate.
\return MEMORY_E if memory allocation fails.
\return Negative error code on other failures.
_Example_
\code
Cert cert;
byte derBuf[4096];
int derSz;
MySignCtx myCtx;
wc_InitCert(&cert);
derSz = wc_MakeCert(&cert, derBuf, sizeof(derBuf), NULL, NULL, &rng);
derSz = wc_SignCert_cb(cert.bodySz, cert.sigType, derBuf, sizeof(derBuf),
RSA_TYPE, mySignCallback, &myCtx, &rng);
if (derSz > 0) {
printf("Signed certificate is %d bytes\n", derSz);
}
\endcode
\sa wc_SignCertCb
\sa wc_SignCert
\sa wc_SignCert_ex
\sa wc_MakeCert
\sa wc_MakeCertReq
*/
int wc_SignCert_cb(int requestSz, int sType, byte* buf, word32 buffSz,
int keyType, wc_SignCertCb signCb, void* signCtx,
WC_RNG* rng);
+111 -45
View File
@@ -20047,61 +20047,127 @@ static int mockSignCb(const byte* in, word32 inLen, byte* out, word32* outLen,
static int test_wc_SignCert_cb(void)
{
EXPECT_DECLS;
#if defined(WOLFSSL_CERT_GEN) && defined(HAVE_ECC) && !defined(NO_ASN_TIME)
Cert cert;
byte der[FOURK_BUF];
int derSize = 0;
WC_RNG rng;
ecc_key key;
MockSignCtx signCtx;
int ret;
#if defined(WOLFSSL_CERT_GEN) && !defined(NO_ASN_TIME)
XMEMSET(&rng, 0, sizeof(WC_RNG));
XMEMSET(&key, 0, sizeof(ecc_key));
XMEMSET(&cert, 0, sizeof(Cert));
XMEMSET(&signCtx, 0, sizeof(MockSignCtx));
#ifdef HAVE_ECC
/* Test with ECC key */
{
Cert cert;
byte der[FOURK_BUF];
int derSize = 0;
WC_RNG rng;
ecc_key key;
MockSignCtx signCtx;
int ret;
ExpectIntEQ(wc_InitRng(&rng), 0);
ExpectIntEQ(wc_ecc_init(&key), 0);
ExpectIntEQ(wc_ecc_make_key(&rng, 32, &key), 0);
ExpectIntEQ(wc_InitCert(&cert), 0);
XMEMSET(&rng, 0, sizeof(WC_RNG));
XMEMSET(&key, 0, sizeof(ecc_key));
XMEMSET(&cert, 0, sizeof(Cert));
XMEMSET(&signCtx, 0, sizeof(MockSignCtx));
(void)XSTRNCPY(cert.subject.country, "US", CTC_NAME_SIZE);
(void)XSTRNCPY(cert.subject.state, "state", CTC_NAME_SIZE);
(void)XSTRNCPY(cert.subject.locality, "locality", CTC_NAME_SIZE);
(void)XSTRNCPY(cert.subject.org, "org", CTC_NAME_SIZE);
(void)XSTRNCPY(cert.subject.unit, "unit", CTC_NAME_SIZE);
(void)XSTRNCPY(cert.subject.commonName, "www.example.com",
CTC_NAME_SIZE);
(void)XSTRNCPY(cert.subject.email, "test@example.com", CTC_NAME_SIZE);
ExpectIntEQ(wc_InitRng(&rng), 0);
ExpectIntEQ(wc_ecc_init(&key), 0);
ExpectIntEQ(wc_ecc_make_key(&rng, 32, &key), 0);
ExpectIntEQ(wc_InitCert(&cert), 0);
cert.selfSigned = 1;
cert.isCA = 0;
cert.sigType = CTC_SHA256wECDSA;
(void)XSTRNCPY(cert.subject.country, "US", CTC_NAME_SIZE);
(void)XSTRNCPY(cert.subject.state, "state", CTC_NAME_SIZE);
(void)XSTRNCPY(cert.subject.locality, "locality", CTC_NAME_SIZE);
(void)XSTRNCPY(cert.subject.org, "org", CTC_NAME_SIZE);
(void)XSTRNCPY(cert.subject.unit, "unit", CTC_NAME_SIZE);
(void)XSTRNCPY(cert.subject.commonName, "www.example.com",
CTC_NAME_SIZE);
(void)XSTRNCPY(cert.subject.email, "test@example.com", CTC_NAME_SIZE);
/* Make cert body */
ExpectIntGT(wc_MakeCert(&cert, der, FOURK_BUF, NULL, &key, &rng), 0);
cert.selfSigned = 1;
cert.isCA = 0;
cert.sigType = CTC_SHA256wECDSA;
/* Setup signing context with key and RNG */
signCtx.key = &key;
signCtx.rng = &rng;
/* Make cert body */
ExpectIntGT(wc_MakeCert(&cert, der, FOURK_BUF, NULL, &key, &rng), 0);
/* Sign using callback API */
ExpectIntGT(derSize = wc_SignCert_cb(cert.bodySz, cert.sigType, der,
FOURK_BUF, ECC_TYPE, mockSignCb, &signCtx, &rng), 0);
/* Setup signing context with key and RNG */
signCtx.key = &key;
signCtx.rng = &rng;
/* Verify the certificate was created properly */
ExpectIntGT(derSize, 0);
/* Sign using callback API */
ExpectIntGT(derSize = wc_SignCert_cb(cert.bodySz, cert.sigType, der,
FOURK_BUF, ECC_TYPE, mockSignCb, &signCtx, &rng), 0);
/* Test error cases */
ExpectIntEQ(wc_SignCert_cb(cert.bodySz, cert.sigType, der,
FOURK_BUF, ECC_TYPE, NULL, &signCtx, &rng), BAD_FUNC_ARG);
/* Verify the certificate was created properly */
ExpectIntGT(derSize, 0);
ret = wc_ecc_free(&key);
ExpectIntEQ(ret, 0);
ret = wc_FreeRng(&rng);
ExpectIntEQ(ret, 0);
#endif
/* Test error cases */
ExpectIntEQ(wc_SignCert_cb(cert.bodySz, cert.sigType, der,
FOURK_BUF, ECC_TYPE, NULL, &signCtx, &rng), BAD_FUNC_ARG);
ret = wc_ecc_free(&key);
ExpectIntEQ(ret, 0);
ret = wc_FreeRng(&rng);
ExpectIntEQ(ret, 0);
}
#endif /* HAVE_ECC */
#if !defined(NO_RSA) && defined(WOLFSSL_KEY_GEN)
/* Test with RSA key */
{
Cert cert;
byte der[FOURK_BUF];
int derSize = 0;
WC_RNG rng;
RsaKey key;
MockSignCtx signCtx;
int ret;
XMEMSET(&rng, 0, sizeof(WC_RNG));
XMEMSET(&key, 0, sizeof(RsaKey));
XMEMSET(&cert, 0, sizeof(Cert));
XMEMSET(&signCtx, 0, sizeof(MockSignCtx));
ExpectIntEQ(wc_InitRng(&rng), 0);
ExpectIntEQ(wc_InitRsaKey(&key, NULL), 0);
ExpectIntEQ(wc_MakeRsaKey(&key, 2048, WC_RSA_EXPONENT, &rng), 0);
ExpectIntEQ(wc_InitCert(&cert), 0);
(void)XSTRNCPY(cert.subject.country, "US", CTC_NAME_SIZE);
(void)XSTRNCPY(cert.subject.state, "state", CTC_NAME_SIZE);
(void)XSTRNCPY(cert.subject.locality, "locality", CTC_NAME_SIZE);
(void)XSTRNCPY(cert.subject.org, "org", CTC_NAME_SIZE);
(void)XSTRNCPY(cert.subject.unit, "unit", CTC_NAME_SIZE);
(void)XSTRNCPY(cert.subject.commonName, "www.example.com",
CTC_NAME_SIZE);
(void)XSTRNCPY(cert.subject.email, "test@example.com", CTC_NAME_SIZE);
cert.selfSigned = 1;
cert.isCA = 0;
cert.sigType = CTC_SHA256wRSA;
/* Make cert body */
ExpectIntGT(wc_MakeCert(&cert, der, FOURK_BUF, &key, NULL, &rng), 0);
/* Setup signing context with key and RNG */
signCtx.key = &key;
signCtx.rng = &rng;
/* Sign using callback API with RSA */
ExpectIntGT(derSize = wc_SignCert_cb(cert.bodySz, cert.sigType, der,
FOURK_BUF, RSA_TYPE, mockSignCb, &signCtx, &rng), 0);
/* Verify the certificate was created properly */
ExpectIntGT(derSize, 0);
/* Test error case - NULL callback */
ExpectIntEQ(wc_SignCert_cb(cert.bodySz, cert.sigType, der,
FOURK_BUF, RSA_TYPE, NULL, &signCtx, &rng), BAD_FUNC_ARG);
ret = wc_FreeRsaKey(&key);
ExpectIntEQ(ret, 0);
ret = wc_FreeRng(&rng);
ExpectIntEQ(ret, 0);
}
#endif /* !NO_RSA && WOLFSSL_KEY_GEN */
#endif /* WOLFSSL_CERT_GEN && !NO_ASN_TIME */
return EXPECT_RESULT();
}
#endif /* WOLFSSL_CERT_SIGN_CB */
View File
-55
View File
@@ -551,61 +551,6 @@ WOLFSSL_API int wc_SignCert_ex(int requestSz, int sType, byte* buf,
WC_RNG* rng);
WOLFSSL_API int wc_SignCert(int requestSz, int sType, byte* buf, word32 buffSz,
RsaKey* rsaKey, ecc_key* eccKey, WC_RNG* rng);
/*!
\ingroup CertManager
\brief Sign a certificate or CSR using a callback function.
This function signs a certificate or Certificate Signing Request (CSR)
using a user-provided signing callback. This allows external signing
implementations (e.g., TPM, HSM) without requiring the crypto callback
infrastructure, making it suitable for FIPS-compliant applications.
The function performs the following:
1. Hashes the certificate/CSR body according to the signature algorithm
2. Encodes the hash (RSA) or prepares it for signing (ECC)
3. Calls the user-provided callback to perform the actual signing
4. Encodes the signature into the certificate/CSR DER structure
\param requestSz Size of the certificate body to sign (from Cert.bodySz).
\param sType Signature algorithm type (e.g., CTC_SHA256wRSA,
CTC_SHA256wECDSA).
\param buf Buffer containing the certificate/CSR DER data to sign.
\param buffSz Total size of the buffer (must be large enough for signature).
\param keyType Type of key used for signing (RSA_TYPE, ECC_TYPE, etc.).
\param signCb User-provided signing callback function.
\param signCtx Context pointer passed to the signing callback.
\param rng Random number generator (may be NULL if not needed).
\return Size of the signed certificate/CSR on success.
\return BAD_FUNC_ARG if signCb is NULL or other parameters are invalid.
\return BUFFER_E if the buffer is too small for the signed certificate.
\return MEMORY_E if memory allocation fails.
\return Negative error code on other failures.
\sa wc_SignCertCb
\sa wc_SignCert
\sa wc_SignCert_ex
\sa wc_MakeCert
\sa wc_MakeCertReq
_Example_
\code
Cert cert;
byte derBuf[4096];
int derSz;
MySignCtx myCtx;
wc_InitCert(&cert);
derSz = wc_MakeCert(&cert, derBuf, sizeof(derBuf), NULL, NULL, &rng);
derSz = wc_SignCert_cb(cert.bodySz, cert.sigType, derBuf, sizeof(derBuf),
RSA_TYPE, mySignCallback, &myCtx, &rng);
if (derSz > 0) {
printf("Signed certificate is %d bytes\n", derSz);
}
\endcode
*/
#ifdef WOLFSSL_CERT_SIGN_CB
WOLFSSL_API int wc_SignCert_cb(int requestSz, int sType, byte* buf,
word32 buffSz, int keyType,