diff options
| author | Bob Beck <[email protected]> | 2026-08-05 19:39:56 +0200 |
|---|---|---|
| committer | Tomas Mraz <[email protected]> | 2026-08-27 15:52:18 +0200 |
| commit | 62570ca6e93af540907330d50ee581fe82cd18fd (patch) | |
| tree | 3448b25337468d8b2fbb57834bf80ceee9962305 /include | |
| parent | Fix one byte overrun in UNIVERSALSTRING_to_string (diff) | |
| download | openssl-62570ca6e93af540907330d50ee581fe82cd18fd.tar.gz openssl-62570ca6e93af540907330d50ee581fe82cd18fd.zip | |
Don't strncpy() counted ASN1_STRING data in ossl_sk_ASN1_UTF8STRING2text()
The element data is counted, not a C string, so strncpy() was wrong two
ways: an empty element yields strncpy(p, NULL, 0), which is undefined, and a
value containing an embedded NUL was truncated and zero padded instead of
copied verbatim.
Use memcpy() bounded by the element length, skipping empty elements. The
separator copy becomes a plain memcpy() as well, dropping the "+ 1 to
silence gcc" strncpy() hack. The computed buffer length and terminator are
unchanged.
Note in the documentation that using utf8 values in C strings is a
footgun if they contain NUL bytes internally
Reviewed-by: Neil Horman <[email protected]>
Reviewed-by: Andrew Dinh <[email protected]>
Reviewed-by: Nikola Pajkovsky <[email protected]>
Merge-date: Thu Aug 27 13:52:44 2026
Merged-from: https://github.com/openssl/openssl/pull/32178
Diffstat (limited to 'include')
| -rw-r--r-- | include/internal/cryptlib.h | 15 |
1 files changed, 15 insertions, 0 deletions
diff --git a/include/internal/cryptlib.h b/include/internal/cryptlib.h index 8bc22e39ce3..1a367b3238b 100644 --- a/include/internal/cryptlib.h +++ b/include/internal/cryptlib.h @@ -154,6 +154,21 @@ const void *ossl_bsearch(const void *key, const void *base, int num, int (*cmp_thunk)(int (*real_cmp_fn)(const void *, const void *), const void *, const void *), int flags); +/** + * @brief Join a stack of ASN1_UTF8STRINGs into one allocated string. + * + * Concatenates the elements of text, separated by sep, into a newly allocated + * NUL terminated string. The element data is copied in full and may itself + * contain embedded NUL bytes, so a caller that treats the result as a C string + * will see it truncated at the first such byte. + * + * @param text the stack of ASN1_UTF8STRINGs to join + * @param sep separator placed between elements, or NULL for none + * @param max_len maximum length of the result, excluding the NUL terminator, + * or 0 for no restriction + * @returns a newly allocated string to be freed with OPENSSL_free(), or NULL on + * error or if the result would exceed max_len + */ char *ossl_sk_ASN1_UTF8STRING2text(STACK_OF(ASN1_UTF8STRING) *text, const char *sep, size_t max_len); char *ossl_ipaddr_to_asc(const unsigned char *p, int len); |
