Fixes to run python with --enable-all#9831
Fixes to run python with --enable-all#9831julek-wolfssl wants to merge 5 commits intowolfSSL:masterfrom
Conversation
There was a problem hiding this comment.
Pull request overview
This PR implements fixes to enable Python compatibility when wolfSSL is built with the --enable-all configuration flag. The changes address version compatibility, hash algorithm support, and cipher suite handling.
Changes:
- Repositioned WOLFSSL_PYTHON version compatibility check to take precedence over other configurations
- Added BLAKE2 hash algorithm support (BLAKE2B and BLAKE2S) throughout the EVP layer
- Refactored cipher suite stack handling to use insertion-based approach instead of manual node linking
Reviewed changes
Copilot reviewed 9 out of 9 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| wolfssl/openssl/opensslv.h | Moved WOLFSSL_PYTHON version definition earlier in conditional chain |
| wolfssl/openssl/evp.h | Added BLAKE2/BLAKE2S includes and union members |
| wolfssl/internal.h | Added declaration for new heap-aware stack creation function |
| wolfcrypt/src/evp.c | Implemented BLAKE2 algorithm support in EVP layer with init, update, and final operations |
| src/x509.c | Fixed registeredID encoding to use DER format and removed conditional serial number handling |
| src/ssl_sk.c | Refactored to use XMEMCPY instead of custom copy function and added heap parameter support |
| src/ssl.c | Simplified cipher suite stack creation using insertion API instead of manual linking |
| src/internal.c | Added max fragment size limiting for send operations |
| .github/workflows/python.yml | Added CI workflow for Python 3.12.11, 3.13.4, and 3.13.7 testing |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
eff79df to
9d4185f
Compare
9d4185f to
6009b6f
Compare
- Add a GitHub Actions workflow to automate testing of Python integration - Implement Blake2b and Blake2s hash functions into the EVP API. - Improve OpenSSL compatibility by standardizing ASN.1 encoding for serial numbers and registered IDs, streamlining cipher stack management, and optimizing stack node copying. - Enforce maximum fragment size during data transmission to ensure proper TLS/DTLS record fragmentation.
fbc8378 to
f9456a2
Compare
f9456a2 to
412d05c
Compare
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 11 out of 11 changed files in this pull request and generated 7 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 12 out of 12 changed files in this pull request and generated 4 comments.
Comments suppressed due to low confidence (1)
src/internal.c:1
wolfSSL_GetMaxFragSize(ssl)is called on every loop iteration. If this value cannot change during the lifetime ofSendData()(typical for max fragment size), compute it once before the loop and reuse it to avoid repeated work on large sends.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| case WC_HASH_TYPE_BLAKE2B: | ||
| case WC_HASH_TYPE_BLAKE2S: | ||
| ret = BAD_FUNC_ARG; |
There was a problem hiding this comment.
BLAKE2B/BLAKE2S are explicitly forced to fail during the hash-context copy switch, even though this PR adds BLAKE2 init/update/final support elsewhere. This will likely break callers that rely on digest context copy (e.g., EVP_MD_CTX_copy / Python hash.copy() semantics). Consider implementing copy support for BLAKE2 when HAVE_BLAKE2/HAVE_BLAKE2S are enabled (using the wolfCrypt copy helper if available, or a well-defined state copy), and keep BAD_FUNC_ARG only for unsupported algorithms.
| case WC_HASH_TYPE_BLAKE2B: | |
| case WC_HASH_TYPE_BLAKE2S: | |
| ret = BAD_FUNC_ARG; | |
| ret = BAD_FUNC_ARG; | |
| break; | |
| case WC_HASH_TYPE_BLAKE2B: | |
| #ifdef HAVE_BLAKE2 | |
| XMEMCPY(&des->hash.digest.blake2b, | |
| &src->hash.digest.blake2b, | |
| (unsigned int)sizeof(src->hash.digest.blake2b)); | |
| ret = 0; | |
| #else | |
| ret = NOT_COMPILED_IN; | |
| #endif | |
| break; | |
| case WC_HASH_TYPE_BLAKE2S: | |
| #ifdef HAVE_BLAKE2S | |
| XMEMCPY(&des->hash.digest.blake2s, | |
| &src->hash.digest.blake2s, | |
| (unsigned int)sizeof(src->hash.digest.blake2s)); | |
| ret = 0; | |
| #else | |
| ret = NOT_COMPILED_IN; | |
| #endif |
| { | ||
| /* Store DER-encoded OID (tag + length + content) in obj */ | ||
| word32 derSz = 1 + SetLength(dns->len, NULL) + dns->len; | ||
| byte* der = (byte*)XMALLOC(derSz, | ||
| gn->d.registeredID->heap, DYNAMIC_TYPE_ASN1); | ||
| if (der == NULL) { | ||
| return WOLFSSL_FAILURE; | ||
| } | ||
| { | ||
| word32 idx = 0; | ||
| der[idx++] = ASN_OBJECT_ID; | ||
| idx += SetLength(dns->len, der + idx); | ||
| XMEMCPY(der + idx, dns->name, dns->len); | ||
| } | ||
| gn->d.registeredID->obj = der; | ||
| gn->d.registeredID->objSz = derSz; | ||
| } | ||
| gn->d.registeredID->dynamic |= WOLFSSL_ASN1_DYNAMIC_DATA; | ||
| XMEMCPY((byte*)gn->d.registeredID->obj, dns->ridString, dns->len); | ||
| gn->d.registeredID->objSz = dns->len; | ||
| gn->d.registeredID->grp = oidCertExtType; | ||
| gn->d.registeredID->nid = WC_NID_registeredAddress; | ||
| break; |
There was a problem hiding this comment.
This changes the source bytes for the registeredID OID payload from dns->ridString (previous code) to dns->name, and it also drops setting gn->d.registeredID->nid (previously WC_NID_registeredAddress). Unless dns->name is guaranteed to contain the raw OID content bytes, this will encode the wrong OID. Additionally, omitting nid may break callers that expect it to be populated for registeredID. Consider restoring the correct source buffer for the OID content and re-adding the nid assignment (and mirror the same fix in the similar block in wolfSSL_X509_get_ext_d2i).
| @@ -331,7 +312,7 @@ void* wolfSSL_sk_pop_node(WOLFSSL_STACK* stack, int idx) | |||
| if (stack->next) { | |||
| /* Keep the first node as it is the pointer passed in. */ | |||
| tmp = stack->next; | |||
There was a problem hiding this comment.
Replacing the previous field-by-field shallow copy with XMEMCPY(..., sizeof(WOLFSSL_STACK)) makes future changes to WOLFSSL_STACK riskier: any newly added fields (ownership flags, heap pointers, bookkeeping, etc.) will now be copied implicitly, which can subtly change semantics compared to the intentionally limited shallow copy. Consider keeping an explicit copy helper that documents which fields are safe/required to copy, or at least add a comment/assertion ensuring WOLFSSL_STACK remains safe to bitwise-copy in these code paths.
| tmp = stack->next; | |
| tmp = stack->next; | |
| /* | |
| * NOTE: This is an intentional whole-struct copy. WOLFSSL_STACK is | |
| * currently treated as a trivially copyable/POD type here. If new | |
| * fields (e.g., ownership flags, heap pointers, bookkeeping) are | |
| * added to WOLFSSL_STACK, this memcpy MUST be revisited to ensure | |
| * that copying those fields preserves correct ownership/semantics. | |
| */ |
| if (i == (int)WOLFSSL_OBJECT_INFO_SZ) { | ||
| WOLFSSL_MSG("NID not in table"); | ||
| #ifdef WOLFSSL_QT | ||
| sName = NULL; | ||
| type = (word32)id; | ||
| #else | ||
| return NULL; |
There was a problem hiding this comment.
This removes the previous WOLFSSL_QT special-case that avoided returning NULL when the NID wasn't in the table. If WOLFSSL_QT builds still rely on the old behavior, this is an observable API/behavior change. If the intent is to keep WOLFSSL_QT compatibility, consider restoring the conditional behavior (or documenting the change and ensuring downstream callers handle NULL).
9e167cc to
7452433
Compare
Depends on wolfSSL/osp#322