-
Notifications
You must be signed in to change notification settings - Fork 922
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?
Conversation
|
Jenkins retest this please. History lost. |
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.
Pull request overview
This pull request adds support for signing certificates and CSRs using a user-provided callback function, enabling integration with external signing devices (TPMs/HSMs) without relying on the crypto callback infrastructure. This is particularly useful for FIPS-compliant applications where offloading cryptographic operations is not acceptable.
Changes:
- Introduced new
wc_SignCert_cbAPI andwc_SignCertCbcallback type for external certificate/CSR signing - Refactored internal
MakeSignaturefunction to use newMakeSignatureCbinternally for RSA and ECC, eliminating code duplication - Added configure option
--enable-certsigncbto enable the feature
Reviewed changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated 8 comments.
| File | Description |
|---|---|
| wolfssl/wolfcrypt/asn_public.h | Added public API declarations for the callback-based certificate signing, including typedef for wc_SignCertCb and function declaration for wc_SignCert_cb |
| wolfcrypt/src/asn.c | Implemented internal MakeSignatureCb function and refactored MakeSignature to use callback path for RSA/ECC; added wc_SignCert_cb implementation |
| tests/api.c | Added test case test_wc_SignCert_cb with mock callback to verify the new API functionality |
| configure.ac | Added configuration option --enable-certsigncb to control compilation of the new feature |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
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.
Pull request overview
Copilot reviewed 4 out of 4 changed files in this pull request and generated 4 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
4dd06e1 to
8e28ab2
Compare
|
Jenkins retest this |
|
Jenkins retest this please. |
dgarske
left a comment
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.
[check-source-text] [2 of 7] [wolfssl]
autogen.sh wolfssl... real 0m17.507s user 0m15.557s sys 0m0.446s
configure... real 0m12.829s user 0m10.049s sys 0m2.680s
trailing whitespace:
./wolfcrypt/src/asn.c:32089:/* Make signature from buffer (sz), write to sig (sigSz)·
./wolfcrypt/src/asn.c:32100:····
./wolfcrypt/src/asn.c:32119:········
./wolfcrypt/src/asn.c:32125:········
./wolfcrypt/src/asn.c:32137:········
C++-style comments:
./wolfssl/wolfcrypt/asn_public.h:269: // Perform signing using external device/HSM
./wolfssl/wolfcrypt/asn_public.h:601: // Initialize cert and set subject, etc.
./wolfssl/wolfcrypt/asn_public.h:603: // ... set cert fields ...
./wolfssl/wolfcrypt/asn_public.h:605: // Make certificate body
./wolfssl/wolfcrypt/asn_public.h:608: // Sign using callback
unescaped error code operands (missing WC_NO_ERR_TRACE()):
wolfcrypt/src/asn.c:32016: int ret = ALGO_ID_E;
|
Jenkins retest this please. |
91d51bd to
1898d4c
Compare
1898d4c to
2cf03da
Compare
2cf03da to
6483a4b
Compare
6483a4b to
8b5bd3b
Compare
lealem47
left a comment
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.
Thanks Jack!
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.
Pull request overview
Copilot reviewed 4 out of 4 changed files in this pull request and generated 3 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| 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, "test@example.com", 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); | ||
|
|
||
| /* 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 */ |
Copilot
AI
Feb 3, 2026
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 function test_wc_SignCert_cb only tests with ECC keys (CTC_SHA256wECDSA). Since the new API explicitly supports both RSA and ECC key types, and the mockSignCb callback implementation includes RSA support (lines 20011-20023), there should be test coverage for RSA as well to ensure the RSA code path works correctly. Consider adding an RSA test case to verify that RSA signing through the callback works properly.
| /* Test error cases */ | ||
| ExpectIntEQ(wc_SignCert_cb(cert.bodySz, cert.sigType, der, | ||
| FOURK_BUF, ECC_TYPE, NULL, &signCtx, &rng), BAD_FUNC_ARG); |
Copilot
AI
Feb 3, 2026
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 checks one error case (NULL callback). Additional error cases should be tested to ensure robust error handling:
- NULL buf parameter (should return BAD_FUNC_ARG per line 34426)
- requestSz < 0 (should return requestSz per line 34432-34434)
- Invalid keyType (to ensure proper error handling)
- Buffer too small (buffSz too small for signature)
These additional test cases would improve confidence in the error handling paths of the new API.
| typedef int (*wc_SignCertCb)(const byte* in, word32 inLen, | ||
| byte* out, word32* outLen, | ||
| int sigAlgo, int keyType, void* ctx); |
Copilot
AI
Feb 3, 2026
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 wc_SignCertCb typedef is not guarded by WOLFSSL_CERT_SIGN_CB, but it's only used in the wc_SignCert_cb function declaration which is guarded (lines 609-614). This creates an inconsistency where the typedef is always defined but the function using it may not be. While this doesn't cause compilation errors (the typedef can exist without the function), it's inconsistent with the pattern used elsewhere in the codebase.
For example, looking at other callback typedefs in the same header file (asn.h), wc_CallbackEccVerify and wc_CallbackRsaVerify are conditionally compiled. The typedef should either be:
- Moved inside the WOLFSSL_CERT_SIGN_CB guard along with the function declaration, or
- Left unguarded if it's intended to be part of the public API regardless of the feature flag (which seems unlikely for a feature-specific callback)
Recommend moving the typedef definition (lines 272-274) inside the WOLFSSL_CERT_SIGN_CB guard block starting at line 609.
This pull request adds support for signing certificates and CSRs using a user-provided callback function, enabling integration with external signing devices (such as TPMs or HSMs) without relying on the crypto callback infrastructure. This is particularly useful for FIPS-compliant applications and scenarios where offloading cryptographic operations is required. The changes include new API definitions, documentation, internal implementation, and tests for the callback-based signing mechanism.
New Callback-Based Certificate Signing API
wc_SignCert_cbfunction and thewc_SignCertCbcallback type, allowing certificates and CSRs to be signed via an external callback for flexible integration with devices like TPMs/HSMs. [1] [2] [3]Internal Implementation
MakeSignatureCbfunction to handle hashing, digest encoding, and invoking the user-provided signing callback, supporting both RSA and ECC key types.Testing
Setup:
TPM simulator: swtpm running on port 2321
Built wolfSSL with: --enable-certgen --enable-certreq --enable-certext --enable-cryptocb
Built wolfTPM with: --enable-swtpm --enable-certgen --enable-debug
Tests Run:
Generated RSA and ECC test keys in TPM
Created CSRs using ./examples/csr/csr
Validated CSRs with openssl req -text -noout
Results:
wc_SignCert_cb compiled into wolfSSL
wolfTPM2_SignCertCb and CSR_MakeAndSign_Cb compiled into wolfTPM
Generated valid RSA (1228 bytes) and ECC (696 bytes) CSRs
CSRs verified successfully with OpenSSL