-
Notifications
You must be signed in to change notification settings - Fork 918
Add wc_SignCert_cb API for external signing callbacks #9632
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
4aa26c1
2e3fa9b
7dbbf74
8616922
2d36f0d
c6dd3f1
d84e1d1
81df4a3
90ce237
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -26920,6 +26920,126 @@ static int test_MakeCertWithCaFalse(void) | |
| return EXPECT_RESULT(); | ||
| } | ||
|
|
||
| /* Mock callback for testing wc_SignCert_cb */ | ||
| #if defined(WOLFSSL_CERT_SIGN_CB) && (defined(WOLFSSL_CERT_GEN) || defined(WOLFSSL_CERT_REQ)) | ||
| /* Context structure for mock signing callback */ | ||
| typedef struct { | ||
| void* key; /* Pointer to RSA or ECC key */ | ||
| WC_RNG* rng; /* Random number generator (required for ECC) */ | ||
| } MockSignCtx; | ||
|
|
||
| static int mockSignCb(const byte* in, word32 inLen, byte* out, word32* outLen, | ||
| int sigAlgo, int keyType, void* ctx) | ||
| { | ||
| int ret = 0; | ||
| MockSignCtx* signCtx = (MockSignCtx*)ctx; | ||
|
|
||
| if (signCtx == NULL || signCtx->key == NULL || in == NULL || | ||
| out == NULL || outLen == NULL) { | ||
| return BAD_FUNC_ARG; | ||
| } | ||
|
|
||
| (void)sigAlgo; | ||
|
|
||
| #ifndef NO_RSA | ||
| if (keyType == RSA_TYPE) { | ||
| RsaKey* rsaKey = (RsaKey*)signCtx->key; | ||
| word32 outSz = *outLen; | ||
|
|
||
| /* For RSA, input is DER-encoded digest (DigestInfo structure) */ | ||
| ret = wc_RsaSSL_Sign(in, inLen, out, outSz, rsaKey, signCtx->rng); | ||
| if (ret > 0) { | ||
| *outLen = (word32)ret; | ||
| ret = 0; | ||
| } | ||
| } | ||
| else | ||
| #endif | ||
| #ifdef HAVE_ECC | ||
| if (keyType == ECC_TYPE) { | ||
| ecc_key* eccKey = (ecc_key*)signCtx->key; | ||
| word32 outSz = *outLen; | ||
|
|
||
| /* For ECC, input is raw hash, sign it (RNG required for ECDSA k value) */ | ||
| ret = wc_ecc_sign_hash(in, inLen, out, &outSz, signCtx->rng, eccKey); | ||
| if (ret == 0) { | ||
| *outLen = outSz; | ||
| } | ||
| } | ||
| else | ||
| #endif | ||
| { | ||
| ret = BAD_FUNC_ARG; | ||
| } | ||
|
|
||
| return ret; | ||
| } | ||
| #endif | ||
|
|
||
| #ifdef WOLFSSL_CERT_SIGN_CB | ||
| 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; | ||
|
|
||
| XMEMSET(&rng, 0, sizeof(WC_RNG)); | ||
| XMEMSET(&key, 0, sizeof(ecc_key)); | ||
| XMEMSET(&cert, 0, sizeof(Cert)); | ||
| XMEMSET(&signCtx, 0, sizeof(MockSignCtx)); | ||
|
|
||
| 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); | ||
|
|
||
| (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, "[email protected]", CTC_NAME_SIZE); | ||
|
|
||
| cert.selfSigned = 1; | ||
| cert.isCA = 0; | ||
| cert.sigType = CTC_SHA256wECDSA; | ||
|
|
||
| /* Make cert body */ | ||
| ExpectIntGT(wc_MakeCert(&cert, der, FOURK_BUF, NULL, &key, &rng), 0); | ||
|
|
||
| /* Setup signing context with key and RNG */ | ||
| signCtx.key = &key; | ||
| signCtx.rng = &rng; | ||
|
|
||
| /* Sign using callback API */ | ||
| ExpectIntGT(derSize = wc_SignCert_cb(cert.bodySz, cert.sigType, der, | ||
| FOURK_BUF, ECC_TYPE, mockSignCb, &signCtx, &rng), 0); | ||
|
Comment on lines
+26980
to
+27024
|
||
|
|
||
| /* Verify the certificate was created properly */ | ||
| ExpectIntGT(derSize, 0); | ||
|
|
||
| /* 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 | ||
| return EXPECT_RESULT(); | ||
| } | ||
| #endif /* WOLFSSL_CERT_SIGN_CB */ | ||
|
|
||
|
|
||
| static int test_wolfSSL_EVP_PKEY_encrypt(void) | ||
| { | ||
| EXPECT_DECLS; | ||
|
|
@@ -41535,6 +41655,9 @@ TEST_CASE testCases[] = { | |
| TEST_DECL(test_MakeCertWithPathLen), | ||
| TEST_DECL(test_MakeCertWith0Ser), | ||
| TEST_DECL(test_MakeCertWithCaFalse), | ||
| #ifdef WOLFSSL_CERT_SIGN_CB | ||
| TEST_DECL(test_wc_SignCert_cb), | ||
| #endif | ||
| TEST_DECL(test_wc_SetKeyUsage), | ||
| TEST_DECL(test_wc_SetAuthKeyIdFromPublicKey_ex), | ||
| TEST_DECL(test_wc_SetSubjectBuffer), | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The test only covers ECC key types, but the API and implementation support both RSA and ECC. Consider adding a test case for RSA to ensure the RSA code path (
wc_RsaSSL_Signin the callback) is also tested and works correctly with the new API.