mirror of
https://github.com/wolfSSL/wolfssl.git
synced 2026-07-06 04:00:49 +02:00
Address PR feedback: move doxygen to proper location and add RSA test coverage
This commit is contained in:
@@ -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
@@ -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 */
|
||||
|
||||
@@ -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,
|
||||
|
||||
Reference in New Issue
Block a user