From 878e7ddbd12308b2e9a5820ac94587b6bcdefa99 Mon Sep 17 00:00:00 2001 From: Juliusz Sosinowicz Date: Mon, 7 Sep 2026 18:14:39 +0000 Subject: [PATCH 1/5] X509_NAME_print_ex: honor ASN1_STRFLGS_ESC_2253 without reversing XN_FLAG_RFC2253 was defined as 1, the same bit as ASN1_STRFLGS_ESC_2253, so a caller asking only for RFC 2253 escaping also got the reversed DN order. OpenVPN master now calls X509_NAME_print_ex() with XN_FLAG_SEP_CPLUS_SPC | XN_FLAG_FN_SN | ASN1_STRFLGS_ESC_2253 | ASN1_STRFLGS_UTF8_CONVERT (fix for CVE-2026-84790) and its ssl_testdriver failed against wolfSSL. - Define XN_FLAG_RFC2253 and XN_FLAG_MULTILINE as OpenSSL does. - Reverse the order only on XN_FLAG_DN_REV. - Implement ASN1_STRFLGS_ESC_2253, ASN1_STRFLGS_ESC_CTRL and ASN1_STRFLGS_ESC_MSB escaping as OpenSSL does. - Write values byte for byte. An embedded NUL previously truncated the value and copied uninitialized heap bytes into the BIO. - Escaping can triple the value length. Reject lengths where the buffer size would overflow. Entries are still always separated by ", " and printed with their short name. XN_FLAG_MULTILINE was 0xFFFF and behaved like XN_FLAG_RFC2253; it now escapes control and non-ASCII bytes and does not reverse the order. --- src/x509.c | 211 +++++++++++++++----------------- tests/api/test_ossl_x509_name.c | 161 ++++++++++++++++++++++++ wolfssl/openssl/x509.h | 13 +- 3 files changed, 272 insertions(+), 113 deletions(-) diff --git a/src/x509.c b/src/x509.c index 55967dc5c15..02a32f551ef 100644 --- a/src/x509.c +++ b/src/x509.c @@ -15601,61 +15601,72 @@ static int get_dn_attr_by_nid(int n, const char** buf) return len; } -/** - * Escape input string for RFC2253 requirements. The following characters - * are escaped with a backslash (\): - * - * 1. A space or '#' at the beginning of the string - * 2. A space at the end of the string - * 3. One of: ",", "+", """, "\", "<", ">", ";" +/* Escape a name entry value. Mirrors OpenSSL's do_esc_char() for single + * byte characters. Only ASN1_STRFLGS_ESC_2253, ASN1_STRFLGS_ESC_CTRL and + * ASN1_STRFLGS_ESC_MSB are implemented. * - * in - input string to escape - * inSz - length of in, not including the null terminator - * out - buffer for output string to be written, will be null terminated - * outSz - size of out + * in - value to escape, may contain NUL bytes + * inSz - length of in + * flags - ASN1_STRFLGS_* flags + * out - buffer for escaped value, NULL to only get the length * - * Returns size of output string (not counting NULL terminator) on success, - * negative on error. + * Returns number of bytes written, or needed when out is NULL. */ -static int wolfSSL_EscapeString_RFC2253(char* in, word32 inSz, - char* out, word32 outSz) +static int wolfssl_x509_name_esc_value(const char* in, int inSz, + unsigned long flags, char* out) { - word32 inIdx = 0; - word32 outIdx = 0; - - if (in == NULL || out == NULL || inSz == 0 || outSz == 0) { - return BAD_FUNC_ARG; - } - - for (inIdx = 0; inIdx < inSz; inIdx++) { + static const char hexDigit[] = "0123456789ABCDEF"; + const unsigned long escFlags = WOLFSSL_ASN1_STRFLGS_ESC_2253 | + WOLFSSL_ASN1_STRFLGS_ESC_CTRL | WOLFSSL_ASN1_STRFLGS_ESC_MSB | + WOLFSSL_ASN1_STRFLGS_ESC_QUOTE; + int i; + int outIdx = 0; - char c = in[inIdx]; + for (i = 0; i < inSz; i++) { + unsigned char c = (unsigned char)in[i]; + int hex = 0; + int bs = 0; - if (((inIdx == 0) && (c == ' ' || c == '#')) || - ((inIdx == (inSz-1)) && (c == ' ')) || - c == ',' || c == '+' || c == '"' || c == '\\' || - c == '<' || c == '>' || c == ';') { + if (c >= 0x80) { + hex = (flags & WOLFSSL_ASN1_STRFLGS_ESC_MSB) != 0; + } + else if ((flags & WOLFSSL_ASN1_STRFLGS_ESC_2253) && + (c == ',' || c == '+' || c == '"' || c == '\\' || + c == '<' || c == '>' || c == ';' || + (i == 0 && (c == ' ' || c == '#')) || + (i == inSz - 1 && c == ' '))) { + bs = 1; + } + else if ((flags & WOLFSSL_ASN1_STRFLGS_ESC_CTRL) && + (c < 0x20 || c == 0x7F)) { + hex = 1; + } + else if (c == '\\' && (flags & escFlags)) { + /* Any escaping means the escape character itself is escaped. */ + bs = 1; + } - if (outIdx > (outSz - 1)) { - return BUFFER_E; + if (hex) { + if (out != NULL) { + out[outIdx] = '\\'; + out[outIdx + 1] = hexDigit[c >> 4]; + out[outIdx + 2] = hexDigit[c & 0x0F]; } - out[outIdx] = '\\'; - outIdx++; + outIdx += 3; } - if (outIdx > (outSz - 1)) { - return BUFFER_E; + else { + if (bs) { + if (out != NULL) + out[outIdx] = '\\'; + outIdx++; + } + if (out != NULL) + out[outIdx] = (char)c; + outIdx++; } - out[outIdx] = c; - outIdx++; } - /* null terminate out */ - if (outIdx > (outSz -1)) { - return BUFFER_E; - } - out[outIdx] = '\0'; - - return (int)outIdx; + return outIdx; } /* @@ -15666,39 +15677,34 @@ static int wolfSSL_EscapeString_RFC2253(char* in, word32 inSz, * indent - number of indent spaces to prepend to name string * flags - flags to control function behavior. Not all flags are currently * supported/implemented. Currently supported are: - * XN_FLAG_RFC2253 - only the backslash escape requirements from - * RFC22523 currently implemented. - * XN_FLAG_DN_REV - print name reversed. Automatically done by - * XN_FLAG_RFC2253. + * XN_FLAG_DN_REV - print name reversed. * XN_FLAG_SPC_EQ - spaces before and after '=' character + * ASN1_STRFLGS_ESC_2253 - backslash escape the RFC 2253 + * special characters in values + * ASN1_STRFLGS_ESC_CTRL - escape control characters as \XX + * ASN1_STRFLGS_ESC_MSB - escape bytes above 0x7F as \XX + * XN_FLAG_RFC2253 combines these as in OpenSSL. Entries are always + * separated by ", " and use their short name. * * Returns WOLFSSL_SUCCESS (1) on success, WOLFSSL_FAILURE (0) on failure. */ int wolfSSL_X509_NAME_print_ex(WOLFSSL_BIO* bio, WOLFSSL_X509_NAME* name, int indent, unsigned long flags) { - int i, count = 0, nameStrSz = 0, escapeSz = 0; - int eqSpace = 0; - char eqStr[4]; - char* tmp = NULL; - char* nameStr = NULL; - const char *buf = NULL; + int i, count = 0; + int eqSz = 1; + const char* eqStr = "="; WOLFSSL_X509_NAME_ENTRY* ne; WOLFSSL_ASN1_STRING* str; - char escaped[ASN_NAME_MAX]; WOLFSSL_ENTER("wolfSSL_X509_NAME_print_ex"); if ((name == NULL) || (bio == NULL)) return WOLFSSL_FAILURE; - XMEMSET(eqStr, 0, sizeof(eqStr)); if (flags & WOLFSSL_XN_FLAG_SPC_EQ) { - eqSpace = 2; - XSTRNCPY(eqStr, " = ", 4); - } - else { - XSTRNCPY(eqStr, "=", 4); + eqStr = " = "; + eqSz = 3; } for (i = 0; i < indent; i++) { @@ -15709,12 +15715,14 @@ int wolfSSL_X509_NAME_print_ex(WOLFSSL_BIO* bio, WOLFSSL_X509_NAME* name, count = wolfSSL_X509_NAME_entry_count(name); for (i = 0; i < count; i++) { - int len; + const char* attr = NULL; + int attrSz; + int valSz; int tmpSz; + int idx; + char* tmp; - /* reverse name order for RFC2253 and DN_REV */ - if ((flags & WOLFSSL_XN_FLAG_RFC2253) || - (flags & WOLFSSL_XN_FLAG_DN_REV)) { + if (flags & WOLFSSL_XN_FLAG_DN_REV) { ne = wolfSSL_X509_NAME_get_entry(name, count - i - 1); } else { @@ -15727,62 +15735,43 @@ int wolfSSL_X509_NAME_print_ex(WOLFSSL_BIO* bio, WOLFSSL_X509_NAME* name, if (str == NULL) return WOLFSSL_FAILURE; - if (flags & WOLFSSL_XN_FLAG_RFC2253) { - /* escape string for RFC 2253, ret sz not counting null term */ - escapeSz = wolfSSL_EscapeString_RFC2253(str->data, - str->length, escaped, sizeof(escaped)); - if (escapeSz < 0) - return WOLFSSL_FAILURE; - - nameStr = escaped; - nameStrSz = escapeSz; - } - else { - nameStr = str->data; - nameStrSz = str->length; - } + /* attrSz is without null terminator */ + attrSz = get_dn_attr_by_nid(ne->nid, &attr); + if (attrSz == 0 || attr == NULL) + return WOLFSSL_FAILURE; - /* len is without null terminator */ - len = get_dn_attr_by_nid(ne->nid, &buf); - if (len == 0 || buf == NULL) + /* escaping can triple the value length */ + if (str->length < 0 || str->length > INT_MAX / 4) return WOLFSSL_FAILURE; - /* + 4 for '=', comma space and '\0'*/ - tmpSz = nameStrSz + len + 4 + eqSpace; - tmp = (char*)XMALLOC(tmpSz, NULL, DYNAMIC_TYPE_TMP_BUFFER); - if (tmp == NULL) { + valSz = wolfssl_x509_name_esc_value(str->data, str->length, flags, + NULL); + + /* attribute, '=', value, ", " and null terminator */ + tmpSz = attrSz + eqSz + valSz + 3; + tmp = (char*)XMALLOC((size_t)tmpSz, NULL, DYNAMIC_TYPE_TMP_BUFFER); + if (tmp == NULL) return WOLFSSL_FAILURE; - } + XMEMCPY(tmp, attr, (size_t)attrSz); + idx = attrSz; + XMEMCPY(tmp + idx, eqStr, (size_t)eqSz); + idx += eqSz; + (void)wolfssl_x509_name_esc_value(str->data, str->length, flags, + tmp + idx); + idx += valSz; if (i < count - 1) { - if (XSNPRINTF(tmp, (size_t)tmpSz, "%s%s%s, ", buf, eqStr, nameStr) - >= tmpSz) - { - WOLFSSL_MSG("buffer overrun"); - XFREE(tmp, NULL, DYNAMIC_TYPE_TMP_BUFFER); - return WOLFSSL_FAILURE; - } - - tmpSz = len + nameStrSz + 3 + eqSpace; /* 3 for '=', comma space */ + XMEMCPY(tmp + idx, ", ", 2); + idx += 2; } - else { - if (XSNPRINTF(tmp, (size_t)tmpSz, "%s%s%s", buf, eqStr, nameStr) - >= tmpSz) - { - WOLFSSL_MSG("buffer overrun"); - XFREE(tmp, NULL, DYNAMIC_TYPE_TMP_BUFFER); - return WOLFSSL_FAILURE; - } - tmpSz = len + nameStrSz + 1 + eqSpace; /* 1 for '=' */ - if (bio->type != WOLFSSL_BIO_FILE && - bio->type != WOLFSSL_BIO_MEMORY) { - ++tmpSz; /* include the terminating null when not writing to a - * file. - */ - } + else if (bio->type != WOLFSSL_BIO_FILE && + bio->type != WOLFSSL_BIO_MEMORY) { + /* include the terminating null when not writing to a file */ + tmp[idx] = '\0'; + idx++; } - if (wolfSSL_BIO_write(bio, tmp, tmpSz) != tmpSz) { + if (wolfSSL_BIO_write(bio, tmp, idx) != idx) { XFREE(tmp, NULL, DYNAMIC_TYPE_TMP_BUFFER); return WOLFSSL_FAILURE; } diff --git a/tests/api/test_ossl_x509_name.c b/tests/api/test_ossl_x509_name.c index c99b781ade3..75636d11f57 100644 --- a/tests/api/test_ossl_x509_name.c +++ b/tests/api/test_ossl_x509_name.c @@ -366,6 +366,16 @@ int test_wolfSSL_X509_NAME_print_ex(void) const char* expNotEscapedRev = "CN=#wolfssl.com<>;, C= US,+\"\\ "; const char* expRFC5523 = "CN=\\#wolfssl.com\\<\\>\\;, C=\\ US\\,\\+\\\"\\\\\\ "; + const char* expEscaped = + "C=\\ US\\,\\+\\\"\\\\\\ , CN=\\#wolfssl.com\\<\\>\\;"; + const unsigned char valNul[] = "with\0null"; + const unsigned char expNul[] = "CN=with\0null"; + const char* expNulCtrl = "CN=with\\00null"; + const unsigned char valBs[] = "a\\b"; + const char* expBsCtrl = "CN=a\\\\b"; + const unsigned char valMsb[] = "\xC3\xA9"; + const char* expMsb = "CN=\\C3\\A9"; + const char* expSpace = "CN=\\ "; /* Test with real cert (svrCertFile) first */ ExpectNotNull(bio = BIO_new(BIO_s_file())); @@ -458,6 +468,17 @@ int test_wolfSSL_X509_NAME_print_ex(void) XN_FLAG_RFC2253), WOLFSSL_SUCCESS); ExpectIntGE((memSz = BIO_get_mem_data(membio, &mem)), 0); ExpectIntEQ(memSz, XSTRLEN(expReverse)); + ExpectIntEQ(XSTRNCMP((char*)mem, expReverse, XSTRLEN(expReverse)), 0); + BIO_free(membio); + membio = NULL; + + /* Test flags: XN_FLAG_MULTILINE - spaces around '=', not reversed */ + ExpectNotNull(membio = BIO_new(BIO_s_mem())); + ExpectIntEQ(X509_NAME_print_ex(membio, name, 0, XN_FLAG_MULTILINE), + WOLFSSL_SUCCESS); + ExpectIntGE((memSz = BIO_get_mem_data(membio, &mem)), 0); + ExpectIntEQ(memSz, XSTRLEN(expEqSpace)); + ExpectIntEQ(XSTRNCMP((char*)mem, expEqSpace, XSTRLEN(expEqSpace)), 0); BIO_free(membio); membio = NULL; @@ -515,6 +536,146 @@ int test_wolfSSL_X509_NAME_print_ex(void) ExpectIntEQ(XSTRNCMP((char*)mem, expNotEscapedRev, XSTRLEN(expNotEscapedRev)), 0); BIO_free(membio); + membio = NULL; + + /* Test flags: ASN1_STRFLGS_ESC_2253 - escaped but not reversed. + * Flags as used by OpenVPN. */ + ExpectNotNull(membio = BIO_new(BIO_s_mem())); + ExpectIntEQ(X509_NAME_print_ex(membio, name, 0, + XN_FLAG_SEP_CPLUS_SPC | XN_FLAG_FN_SN | + ASN1_STRFLGS_ESC_2253 | ASN1_STRFLGS_UTF8_CONVERT), + WOLFSSL_SUCCESS); + ExpectIntGE((memSz = BIO_get_mem_data(membio, &mem)), 0); + ExpectIntEQ(memSz, XSTRLEN(expEscaped)); + ExpectIntEQ(XSTRNCMP((char*)mem, expEscaped, XSTRLEN(expEscaped)), 0); + BIO_free(membio); + membio = NULL; + + /* Test flags: XN_FLAG_RFC2253 without XN_FLAG_DN_REV - escaped but + * not reversed */ + ExpectNotNull(membio = BIO_new(BIO_s_mem())); + ExpectIntEQ(X509_NAME_print_ex(membio, name, 0, + XN_FLAG_RFC2253 & ~XN_FLAG_DN_REV), WOLFSSL_SUCCESS); + ExpectIntGE((memSz = BIO_get_mem_data(membio, &mem)), 0); + ExpectIntEQ(memSz, XSTRLEN(expEscaped)); + ExpectIntEQ(XSTRNCMP((char*)mem, expEscaped, XSTRLEN(expEscaped)), 0); + BIO_free(membio); + membio = NULL; + + X509_NAME_free(name); + name = NULL; + } + + /* Test NUL, control and non-ASCII bytes in values */ + { + ExpectNotNull(name = X509_NAME_new()); + ExpectIntEQ(X509_NAME_add_entry_by_txt(name, "commonName", + MBSTRING_UTF8, valNul, sizeof(valNul) - 1, -1, 0), + WOLFSSL_SUCCESS); + + /* Test without flags - NUL byte is written as is. OpenSSL falls + * back to X509_NAME_print() here and escapes it. */ + ExpectNotNull(membio = BIO_new(BIO_s_mem())); + ExpectIntEQ(X509_NAME_print_ex(membio, name, 0, 0), WOLFSSL_SUCCESS); + ExpectIntGE((memSz = BIO_get_mem_data(membio, &mem)), 0); + ExpectIntEQ(memSz, sizeof(expNul) - 1); + ExpectIntEQ(XMEMCMP(mem, expNul, sizeof(expNul) - 1), 0); + BIO_free(membio); + membio = NULL; + + /* Test flags: ASN1_STRFLGS_ESC_2253 - NUL byte is written as is */ + ExpectNotNull(membio = BIO_new(BIO_s_mem())); + ExpectIntEQ(X509_NAME_print_ex(membio, name, 0, + XN_FLAG_SEP_CPLUS_SPC | XN_FLAG_FN_SN | + ASN1_STRFLGS_ESC_2253 | ASN1_STRFLGS_UTF8_CONVERT), + WOLFSSL_SUCCESS); + ExpectIntGE((memSz = BIO_get_mem_data(membio, &mem)), 0); + ExpectIntEQ(memSz, sizeof(expNul) - 1); + ExpectIntEQ(XMEMCMP(mem, expNul, sizeof(expNul) - 1), 0); + BIO_free(membio); + membio = NULL; + + /* Test flags: ASN1_STRFLGS_ESC_CTRL - NUL byte is escaped */ + ExpectNotNull(membio = BIO_new(BIO_s_mem())); + ExpectIntEQ(X509_NAME_print_ex(membio, name, 0, + XN_FLAG_SEP_CPLUS_SPC | ASN1_STRFLGS_ESC_CTRL | + ASN1_STRFLGS_UTF8_CONVERT), WOLFSSL_SUCCESS); + ExpectIntGE((memSz = BIO_get_mem_data(membio, &mem)), 0); + ExpectIntEQ(memSz, XSTRLEN(expNulCtrl)); + ExpectIntEQ(XSTRNCMP((char*)mem, expNulCtrl, XSTRLEN(expNulCtrl)), 0); + BIO_free(membio); + membio = NULL; + + X509_NAME_free(name); + name = NULL; + + /* Backslash is escaped whenever any escaping is done */ + ExpectNotNull(name = X509_NAME_new()); + ExpectIntEQ(X509_NAME_add_entry_by_txt(name, "commonName", + MBSTRING_UTF8, valBs, sizeof(valBs) - 1, -1, 0), + WOLFSSL_SUCCESS); + ExpectNotNull(membio = BIO_new(BIO_s_mem())); + ExpectIntEQ(X509_NAME_print_ex(membio, name, 0, + XN_FLAG_SEP_CPLUS_SPC | ASN1_STRFLGS_ESC_CTRL | + ASN1_STRFLGS_UTF8_CONVERT), WOLFSSL_SUCCESS); + ExpectIntGE((memSz = BIO_get_mem_data(membio, &mem)), 0); + ExpectIntEQ(memSz, XSTRLEN(expBsCtrl)); + ExpectIntEQ(XSTRNCMP((char*)mem, expBsCtrl, XSTRLEN(expBsCtrl)), 0); + BIO_free(membio); + membio = NULL; + X509_NAME_free(name); + name = NULL; + + ExpectNotNull(name = X509_NAME_new()); + ExpectIntEQ(X509_NAME_add_entry_by_txt(name, "commonName", + MBSTRING_UTF8, valMsb, sizeof(valMsb) - 1, -1, 0), + WOLFSSL_SUCCESS); + + /* Test without flags - non-ASCII bytes are written as is */ + ExpectNotNull(membio = BIO_new(BIO_s_mem())); + ExpectIntEQ(X509_NAME_print_ex(membio, name, 0, 0), WOLFSSL_SUCCESS); + ExpectIntGE((memSz = BIO_get_mem_data(membio, &mem)), 0); + ExpectIntEQ(memSz, 3 + sizeof(valMsb) - 1); + ExpectIntEQ(XMEMCMP(mem + 3, valMsb, sizeof(valMsb) - 1), 0); + BIO_free(membio); + membio = NULL; + + /* Test flags: ASN1_STRFLGS_ESC_MSB - non-ASCII bytes are escaped */ + ExpectNotNull(membio = BIO_new(BIO_s_mem())); + ExpectIntEQ(X509_NAME_print_ex(membio, name, 0, + XN_FLAG_SEP_CPLUS_SPC | ASN1_STRFLGS_ESC_MSB | + ASN1_STRFLGS_UTF8_CONVERT), WOLFSSL_SUCCESS); + ExpectIntGE((memSz = BIO_get_mem_data(membio, &mem)), 0); + ExpectIntEQ(memSz, XSTRLEN(expMsb)); + ExpectIntEQ(XSTRNCMP((char*)mem, expMsb, XSTRLEN(expMsb)), 0); + BIO_free(membio); + membio = NULL; + + /* Test flags: XN_FLAG_RFC2253 - includes ASN1_STRFLGS_ESC_MSB */ + ExpectNotNull(membio = BIO_new(BIO_s_mem())); + ExpectIntEQ(X509_NAME_print_ex(membio, name, 0, + XN_FLAG_RFC2253), WOLFSSL_SUCCESS); + ExpectIntGE((memSz = BIO_get_mem_data(membio, &mem)), 0); + ExpectIntEQ(memSz, XSTRLEN(expMsb)); + ExpectIntEQ(XSTRNCMP((char*)mem, expMsb, XSTRLEN(expMsb)), 0); + BIO_free(membio); + membio = NULL; + X509_NAME_free(name); + name = NULL; + + /* A lone space is both a leading and a trailing space */ + ExpectNotNull(name = X509_NAME_new()); + ExpectIntEQ(X509_NAME_add_entry_by_txt(name, "commonName", + MBSTRING_UTF8, (const byte*)" ", 1, -1, 0), + WOLFSSL_SUCCESS); + ExpectNotNull(membio = BIO_new(BIO_s_mem())); + ExpectIntEQ(X509_NAME_print_ex(membio, name, 0, + XN_FLAG_SEP_CPLUS_SPC | ASN1_STRFLGS_ESC_2253 | + ASN1_STRFLGS_UTF8_CONVERT), WOLFSSL_SUCCESS); + ExpectIntGE((memSz = BIO_get_mem_data(membio, &mem)), 0); + ExpectIntEQ(memSz, XSTRLEN(expSpace)); + ExpectIntEQ(XSTRNCMP((char*)mem, expSpace, XSTRLEN(expSpace)), 0); + BIO_free(membio); X509_NAME_free(name); } diff --git a/wolfssl/openssl/x509.h b/wolfssl/openssl/x509.h index 5dd01797cc7..fc30b5818d1 100644 --- a/wolfssl/openssl/x509.h +++ b/wolfssl/openssl/x509.h @@ -50,7 +50,6 @@ #define WOLFSSL_XN_FLAG_FN_SN 0 #define WOLFSSL_XN_FLAG_COMPAT 0 -#define WOLFSSL_XN_FLAG_RFC2253 1 #define WOLFSSL_XN_FLAG_SEP_COMMA_PLUS (1 << 16) #define WOLFSSL_XN_FLAG_SEP_CPLUS_SPC (2 << 16) #define WOLFSSL_XN_FLAG_SEP_SPLUS_SPC (3 << 16) @@ -65,7 +64,17 @@ #define WOLFSSL_XN_FLAG_DUMP_UNKNOWN_FIELDS (1 << 24) #define WOLFSSL_XN_FLAG_FN_ALIGN (1 << 25) -#define WOLFSSL_XN_FLAG_MULTILINE 0xFFFF +#define WOLFSSL_XN_FLAG_RFC2253 (WOLFSSL_ASN1_STRFLGS_RFC2253 | \ + WOLFSSL_XN_FLAG_SEP_COMMA_PLUS | \ + WOLFSSL_XN_FLAG_DN_REV | \ + WOLFSSL_XN_FLAG_FN_SN | \ + WOLFSSL_XN_FLAG_DUMP_UNKNOWN_FIELDS) +#define WOLFSSL_XN_FLAG_MULTILINE (WOLFSSL_ASN1_STRFLGS_ESC_CTRL | \ + WOLFSSL_ASN1_STRFLGS_ESC_MSB | \ + WOLFSSL_XN_FLAG_SEP_MULTILINE | \ + WOLFSSL_XN_FLAG_SPC_EQ | \ + WOLFSSL_XN_FLAG_FN_LN | \ + WOLFSSL_XN_FLAG_FN_ALIGN) #define WOLFSSL_XN_FLAG_ONELINE (WOLFSSL_XN_FLAG_SEP_CPLUS_SPC | WOLFSSL_XN_FLAG_SPC_EQ | WOLFSSL_XN_FLAG_FN_SN) #ifndef OPENSSL_COEXIST From 863936e80f4298d1cb175afe14e0003c51312dc5 Mon Sep 17 00:00:00 2001 From: Juliusz Sosinowicz Date: Mon, 7 Sep 2026 18:56:01 +0000 Subject: [PATCH 2/5] X509_NAME_print_ex: clarify comments on ESC_QUOTE and memory BIOs --- src/x509.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/x509.c b/src/x509.c index 02a32f551ef..b8913990e16 100644 --- a/src/x509.c +++ b/src/x509.c @@ -15603,7 +15603,8 @@ static int get_dn_attr_by_nid(int n, const char** buf) /* Escape a name entry value. Mirrors OpenSSL's do_esc_char() for single * byte characters. Only ASN1_STRFLGS_ESC_2253, ASN1_STRFLGS_ESC_CTRL and - * ASN1_STRFLGS_ESC_MSB are implemented. + * ASN1_STRFLGS_ESC_MSB are implemented. ASN1_STRFLGS_ESC_QUOTE does not + * quote but, as in OpenSSL, still causes the backslash to be escaped. * * in - value to escape, may contain NUL bytes * inSz - length of in @@ -15766,7 +15767,8 @@ int wolfSSL_X509_NAME_print_ex(WOLFSSL_BIO* bio, WOLFSSL_X509_NAME* name, } else if (bio->type != WOLFSSL_BIO_FILE && bio->type != WOLFSSL_BIO_MEMORY) { - /* include the terminating null when not writing to a file */ + /* include the terminating null when not writing to a file or + * memory BIO */ tmp[idx] = '\0'; idx++; } From f299ad00971d25489135941b1c70c1f315528274 Mon Sep 17 00:00:00 2001 From: Juliusz Sosinowicz Date: Mon, 7 Sep 2026 21:57:52 +0000 Subject: [PATCH 3/5] X509_NAME_print_ex: never write a terminating NUL The NUL was once written for every BIO type and later limited to BIOs that are not files or memory. It made the output depend on the BIO type and contradicted the function comment. --- src/x509.c | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/src/x509.c b/src/x509.c index b8913990e16..a6febac2d17 100644 --- a/src/x509.c +++ b/src/x509.c @@ -15748,8 +15748,8 @@ int wolfSSL_X509_NAME_print_ex(WOLFSSL_BIO* bio, WOLFSSL_X509_NAME* name, valSz = wolfssl_x509_name_esc_value(str->data, str->length, flags, NULL); - /* attribute, '=', value, ", " and null terminator */ - tmpSz = attrSz + eqSz + valSz + 3; + /* attribute, '=', value and ", " */ + tmpSz = attrSz + eqSz + valSz + 2; tmp = (char*)XMALLOC((size_t)tmpSz, NULL, DYNAMIC_TYPE_TMP_BUFFER); if (tmp == NULL) return WOLFSSL_FAILURE; @@ -15765,13 +15765,6 @@ int wolfSSL_X509_NAME_print_ex(WOLFSSL_BIO* bio, WOLFSSL_X509_NAME* name, XMEMCPY(tmp + idx, ", ", 2); idx += 2; } - else if (bio->type != WOLFSSL_BIO_FILE && - bio->type != WOLFSSL_BIO_MEMORY) { - /* include the terminating null when not writing to a file or - * memory BIO */ - tmp[idx] = '\0'; - idx++; - } if (wolfSSL_BIO_write(bio, tmp, idx) != idx) { XFREE(tmp, NULL, DYNAMIC_TYPE_TMP_BUFFER); From 88bf23ffb33c3c9574cd4628266cb3f8021735a0 Mon Sep 17 00:00:00 2001 From: Juliusz Sosinowicz Date: Tue, 8 Sep 2026 08:23:42 +0000 Subject: [PATCH 4/5] X509_NAME_print_ex: honor separator and attribute name flags Separate entries with ",", ", ", "; " or a new line for XN_FLAG_SEP_COMMA_PLUS, XN_FLAG_SEP_CPLUS_SPC, XN_FLAG_SEP_SPLUS_SPC and XN_FLAG_SEP_MULTILINE, indenting every line for the last one. Print long names for XN_FLAG_FN_LN, no name for XN_FLAG_FN_NONE and pad names for XN_FLAG_FN_ALIGN, as OpenSSL does. XN_FLAG_FN_OID still prints short names as wolfSSL has no OIDs for name attributes. XN_FLAG_RFC2253 output changes from "CN=a, C=b" to "CN=a,C=b". --- src/x509.c | 111 ++++++++++++++++++++++++++------ tests/api/test_ossl_x509_name.c | 104 +++++++++++++++++++++++++++--- wolfssl/openssl/x509.h | 2 + 3 files changed, 187 insertions(+), 30 deletions(-) diff --git a/src/x509.c b/src/x509.c index a6febac2d17..cf4d0815e6c 100644 --- a/src/x509.c +++ b/src/x509.c @@ -15675,17 +15675,24 @@ static int wolfssl_x509_name_esc_value(const char* in, int inSz, * * bio - output BIO to place name string. Does not include null terminator. * name - input name to convert to string - * indent - number of indent spaces to prepend to name string - * flags - flags to control function behavior. Not all flags are currently - * supported/implemented. Currently supported are: - * XN_FLAG_DN_REV - print name reversed. - * XN_FLAG_SPC_EQ - spaces before and after '=' character + * indent - number of indent spaces to prepend to name string, and to every + * line with XN_FLAG_SEP_MULTILINE + * flags - flags to control function behavior, as in OpenSSL: + * XN_FLAG_SEP_COMMA_PLUS, XN_FLAG_SEP_CPLUS_SPC, + * XN_FLAG_SEP_SPLUS_SPC, XN_FLAG_SEP_MULTILINE - entry + * separator, ", " when none is set + * XN_FLAG_FN_SN, XN_FLAG_FN_LN, XN_FLAG_FN_NONE - attribute + * name style, XN_FLAG_FN_OID prints + * short names + * XN_FLAG_FN_ALIGN - pad the attribute name + * XN_FLAG_DN_REV - print name reversed + * XN_FLAG_SPC_EQ - spaces before and after '=' * ASN1_STRFLGS_ESC_2253 - backslash escape the RFC 2253 * special characters in values * ASN1_STRFLGS_ESC_CTRL - escape control characters as \XX * ASN1_STRFLGS_ESC_MSB - escape bytes above 0x7F as \XX - * XN_FLAG_RFC2253 combines these as in OpenSSL. Entries are always - * separated by ", " and use their short name. + * Multi-valued RDNs are flattened: their attributes are separated + * like RDNs. * * Returns WOLFSSL_SUCCESS (1) on success, WOLFSSL_FAILURE (0) on failure. */ @@ -15695,6 +15702,11 @@ int wolfSSL_X509_NAME_print_ex(WOLFSSL_BIO* bio, WOLFSSL_X509_NAME* name, int i, count = 0; int eqSz = 1; const char* eqStr = "="; + int sepSz = 2; + const char* sep = ", "; + int lineIndent = 0; + int fnOpt; + int fnWidth = 0; WOLFSSL_X509_NAME_ENTRY* ne; WOLFSSL_ASN1_STRING* str; @@ -15703,11 +15715,41 @@ int wolfSSL_X509_NAME_print_ex(WOLFSSL_BIO* bio, WOLFSSL_X509_NAME* name, if ((name == NULL) || (bio == NULL)) return WOLFSSL_FAILURE; + if (indent < 0) + indent = 0; + + switch (flags & WOLFSSL_XN_FLAG_SEP_MASK) { + case WOLFSSL_XN_FLAG_SEP_COMMA_PLUS: + sep = ","; + sepSz = 1; + break; + case WOLFSSL_XN_FLAG_SEP_SPLUS_SPC: + sep = "; "; + sepSz = 2; + break; + case WOLFSSL_XN_FLAG_SEP_MULTILINE: + sep = "\n"; + sepSz = 1; + lineIndent = indent; + break; + default: + /* XN_FLAG_SEP_CPLUS_SPC or no separator flag */ + break; + } + if (flags & WOLFSSL_XN_FLAG_SPC_EQ) { eqStr = " = "; eqSz = 3; } + fnOpt = (int)(flags & WOLFSSL_XN_FLAG_FN_MASK); + if (flags & WOLFSSL_XN_FLAG_FN_ALIGN) { + if (fnOpt == WOLFSSL_XN_FLAG_FN_SN) + fnWidth = 10; + else if (fnOpt == WOLFSSL_XN_FLAG_FN_LN) + fnWidth = 25; + } + for (i = 0; i < indent; i++) { if (wolfSSL_BIO_write(bio, " ", 1) != 1) return WOLFSSL_FAILURE; @@ -15717,10 +15759,12 @@ int wolfSSL_X509_NAME_print_ex(WOLFSSL_BIO* bio, WOLFSSL_X509_NAME* name, for (i = 0; i < count; i++) { const char* attr = NULL; - int attrSz; + int attrSz = 0; + int padSz = 0; int valSz; int tmpSz; int idx; + int j; char* tmp; if (flags & WOLFSSL_XN_FLAG_DN_REV) { @@ -15736,10 +15780,25 @@ int wolfSSL_X509_NAME_print_ex(WOLFSSL_BIO* bio, WOLFSSL_X509_NAME* name, if (str == NULL) return WOLFSSL_FAILURE; - /* attrSz is without null terminator */ - attrSz = get_dn_attr_by_nid(ne->nid, &attr); - if (attrSz == 0 || attr == NULL) - return WOLFSSL_FAILURE; + if (fnOpt == WOLFSSL_XN_FLAG_FN_NONE) { + /* no attribute name */ + } +#ifdef OPENSSL_EXTRA + else if (fnOpt == WOLFSSL_XN_FLAG_FN_LN) { + attr = wolfSSL_OBJ_nid2ln(ne->nid); + if (attr == NULL) + return WOLFSSL_FAILURE; + attrSz = (int)XSTRLEN(attr); + } +#endif + else { + /* attrSz is without null terminator */ + attrSz = get_dn_attr_by_nid(ne->nid, &attr); + if (attrSz == 0 || attr == NULL) + return WOLFSSL_FAILURE; + } + if (attrSz < fnWidth) + padSz = fnWidth - attrSz; /* escaping can triple the value length */ if (str->length < 0 || str->length > INT_MAX / 4) @@ -15748,22 +15807,27 @@ int wolfSSL_X509_NAME_print_ex(WOLFSSL_BIO* bio, WOLFSSL_X509_NAME* name, valSz = wolfssl_x509_name_esc_value(str->data, str->length, flags, NULL); - /* attribute, '=', value and ", " */ - tmpSz = attrSz + eqSz + valSz + 2; + /* attribute, padding, '=', value and separator, +1 for empty */ + tmpSz = attrSz + padSz + eqSz + valSz + sepSz + 1; tmp = (char*)XMALLOC((size_t)tmpSz, NULL, DYNAMIC_TYPE_TMP_BUFFER); if (tmp == NULL) return WOLFSSL_FAILURE; - XMEMCPY(tmp, attr, (size_t)attrSz); - idx = attrSz; - XMEMCPY(tmp + idx, eqStr, (size_t)eqSz); - idx += eqSz; + idx = 0; + if (fnOpt != WOLFSSL_XN_FLAG_FN_NONE) { + XMEMCPY(tmp, attr, (size_t)attrSz); + idx = attrSz; + XMEMSET(tmp + idx, ' ', (size_t)padSz); + idx += padSz; + XMEMCPY(tmp + idx, eqStr, (size_t)eqSz); + idx += eqSz; + } (void)wolfssl_x509_name_esc_value(str->data, str->length, flags, tmp + idx); idx += valSz; if (i < count - 1) { - XMEMCPY(tmp + idx, ", ", 2); - idx += 2; + XMEMCPY(tmp + idx, sep, (size_t)sepSz); + idx += sepSz; } if (wolfSSL_BIO_write(bio, tmp, idx) != idx) { @@ -15772,6 +15836,13 @@ int wolfSSL_X509_NAME_print_ex(WOLFSSL_BIO* bio, WOLFSSL_X509_NAME* name, } XFREE(tmp, NULL, DYNAMIC_TYPE_TMP_BUFFER); + + if (i < count - 1) { + for (j = 0; j < lineIndent; j++) { + if (wolfSSL_BIO_write(bio, " ", 1) != 1) + return WOLFSSL_FAILURE; + } + } } return WOLFSSL_SUCCESS; diff --git a/tests/api/test_ossl_x509_name.c b/tests/api/test_ossl_x509_name.c index 75636d11f57..b3a4f2eaa77 100644 --- a/tests/api/test_ossl_x509_name.c +++ b/tests/api/test_ossl_x509_name.c @@ -361,13 +361,27 @@ int test_wolfSSL_X509_NAME_print_ex(void) const char* expNormal = "C=US, CN=wolfssl.com"; const char* expEqSpace = "C = US, CN = wolfssl.com"; const char* expReverse = "CN=wolfssl.com, C=US"; + const char* expRFC2253 = "CN=wolfssl.com,C=US"; + const char* expMultiline = + "countryName = US\n" + "commonName = wolfssl.com"; + const char* expMultilineInd = + " countryName = US\n" + " commonName = wolfssl.com"; + const char* expSemi = "C=US; CN=wolfssl.com"; + const char* expNoName = "US, wolfssl.com"; + const char* expLongName = "countryName=US, commonName=wolfssl.com"; + const char* expAligned = "C =US, CN =wolfssl.com"; + const char* expIndent = " C=US, CN=wolfssl.com"; const char* expNotEscaped = "C= US,+\"\\ , CN=#wolfssl.com<>;"; const char* expNotEscapedRev = "CN=#wolfssl.com<>;, C= US,+\"\\ "; const char* expRFC5523 = - "CN=\\#wolfssl.com\\<\\>\\;, C=\\ US\\,\\+\\\"\\\\\\ "; + "CN=\\#wolfssl.com\\<\\>\\;,C=\\ US\\,\\+\\\"\\\\\\ "; const char* expEscaped = "C=\\ US\\,\\+\\\"\\\\\\ , CN=\\#wolfssl.com\\<\\>\\;"; + const char* expEscapedComma = + "C=\\ US\\,\\+\\\"\\\\\\ ,CN=\\#wolfssl.com\\<\\>\\;"; const unsigned char valNul[] = "with\0null"; const unsigned char expNul[] = "CN=with\0null"; const char* expNulCtrl = "CN=with\\00null"; @@ -462,23 +476,92 @@ int test_wolfSSL_X509_NAME_print_ex(void) BIO_free(membio); membio = NULL; - /* Test flags: XN_FLAG_RFC2253 - should be reversed */ + /* Test flags: XN_FLAG_RFC2253 - reversed, comma separated */ ExpectNotNull(membio = BIO_new(BIO_s_mem())); ExpectIntEQ(X509_NAME_print_ex(membio, name, 0, XN_FLAG_RFC2253), WOLFSSL_SUCCESS); ExpectIntGE((memSz = BIO_get_mem_data(membio, &mem)), 0); - ExpectIntEQ(memSz, XSTRLEN(expReverse)); - ExpectIntEQ(XSTRNCMP((char*)mem, expReverse, XSTRLEN(expReverse)), 0); + ExpectIntEQ(memSz, XSTRLEN(expRFC2253)); + ExpectIntEQ(XSTRNCMP((char*)mem, expRFC2253, XSTRLEN(expRFC2253)), 0); BIO_free(membio); membio = NULL; - /* Test flags: XN_FLAG_MULTILINE - spaces around '=', not reversed */ + /* Test flags: XN_FLAG_MULTILINE - one entry per line, long names + * aligned, spaces around '=' */ ExpectNotNull(membio = BIO_new(BIO_s_mem())); ExpectIntEQ(X509_NAME_print_ex(membio, name, 0, XN_FLAG_MULTILINE), WOLFSSL_SUCCESS); ExpectIntGE((memSz = BIO_get_mem_data(membio, &mem)), 0); - ExpectIntEQ(memSz, XSTRLEN(expEqSpace)); - ExpectIntEQ(XSTRNCMP((char*)mem, expEqSpace, XSTRLEN(expEqSpace)), 0); + ExpectIntEQ(memSz, XSTRLEN(expMultiline)); + ExpectIntEQ(XSTRNCMP((char*)mem, expMultiline, XSTRLEN(expMultiline)), + 0); + BIO_free(membio); + membio = NULL; + + /* Test flags: XN_FLAG_MULTILINE with indent - every line indented */ + ExpectNotNull(membio = BIO_new(BIO_s_mem())); + ExpectIntEQ(X509_NAME_print_ex(membio, name, 2, XN_FLAG_MULTILINE), + WOLFSSL_SUCCESS); + ExpectIntGE((memSz = BIO_get_mem_data(membio, &mem)), 0); + ExpectIntEQ(memSz, XSTRLEN(expMultilineInd)); + ExpectIntEQ(XSTRNCMP((char*)mem, expMultilineInd, + XSTRLEN(expMultilineInd)), 0); + BIO_free(membio); + membio = NULL; + + /* Test flags: XN_FLAG_SEP_SPLUS_SPC */ + ExpectNotNull(membio = BIO_new(BIO_s_mem())); + ExpectIntEQ(X509_NAME_print_ex(membio, name, 0, + XN_FLAG_SEP_SPLUS_SPC | ASN1_STRFLGS_ESC_2253 | + ASN1_STRFLGS_UTF8_CONVERT), WOLFSSL_SUCCESS); + ExpectIntGE((memSz = BIO_get_mem_data(membio, &mem)), 0); + ExpectIntEQ(memSz, XSTRLEN(expSemi)); + ExpectIntEQ(XSTRNCMP((char*)mem, expSemi, XSTRLEN(expSemi)), 0); + BIO_free(membio); + membio = NULL; + + /* Test flags: XN_FLAG_FN_NONE */ + ExpectNotNull(membio = BIO_new(BIO_s_mem())); + ExpectIntEQ(X509_NAME_print_ex(membio, name, 0, + XN_FLAG_SEP_CPLUS_SPC | XN_FLAG_FN_NONE | + ASN1_STRFLGS_UTF8_CONVERT), WOLFSSL_SUCCESS); + ExpectIntGE((memSz = BIO_get_mem_data(membio, &mem)), 0); + ExpectIntEQ(memSz, XSTRLEN(expNoName)); + ExpectIntEQ(XSTRNCMP((char*)mem, expNoName, XSTRLEN(expNoName)), 0); + BIO_free(membio); + membio = NULL; + + /* Test flags: XN_FLAG_FN_LN */ + ExpectNotNull(membio = BIO_new(BIO_s_mem())); + ExpectIntEQ(X509_NAME_print_ex(membio, name, 0, + XN_FLAG_SEP_CPLUS_SPC | XN_FLAG_FN_LN | + ASN1_STRFLGS_UTF8_CONVERT), WOLFSSL_SUCCESS); + ExpectIntGE((memSz = BIO_get_mem_data(membio, &mem)), 0); + ExpectIntEQ(memSz, XSTRLEN(expLongName)); + ExpectIntEQ(XSTRNCMP((char*)mem, expLongName, XSTRLEN(expLongName)), + 0); + BIO_free(membio); + membio = NULL; + + /* Test flags: XN_FLAG_FN_SN | XN_FLAG_FN_ALIGN */ + ExpectNotNull(membio = BIO_new(BIO_s_mem())); + ExpectIntEQ(X509_NAME_print_ex(membio, name, 0, + XN_FLAG_SEP_CPLUS_SPC | XN_FLAG_FN_SN | XN_FLAG_FN_ALIGN | + ASN1_STRFLGS_UTF8_CONVERT), WOLFSSL_SUCCESS); + ExpectIntGE((memSz = BIO_get_mem_data(membio, &mem)), 0); + ExpectIntEQ(memSz, XSTRLEN(expAligned)); + ExpectIntEQ(XSTRNCMP((char*)mem, expAligned, XSTRLEN(expAligned)), 0); + BIO_free(membio); + membio = NULL; + + /* Test indent without XN_FLAG_SEP_MULTILINE - only the first line */ + ExpectNotNull(membio = BIO_new(BIO_s_mem())); + ExpectIntEQ(X509_NAME_print_ex(membio, name, 3, + XN_FLAG_SEP_CPLUS_SPC | ASN1_STRFLGS_UTF8_CONVERT), + WOLFSSL_SUCCESS); + ExpectIntGE((memSz = BIO_get_mem_data(membio, &mem)), 0); + ExpectIntEQ(memSz, XSTRLEN(expIndent)); + ExpectIntEQ(XSTRNCMP((char*)mem, expIndent, XSTRLEN(expIndent)), 0); BIO_free(membio); membio = NULL; @@ -517,7 +600,7 @@ int test_wolfSSL_X509_NAME_print_ex(void) BIO_free(membio); membio = NULL; - /* Test flags: XN_FLAG_RFC5523 - should be reversed and escaped */ + /* Test flags: XN_FLAG_RFC2253 - reversed, escaped, comma separated */ ExpectNotNull(membio = BIO_new(BIO_s_mem())); ExpectIntEQ(X509_NAME_print_ex(membio, name, 0, XN_FLAG_RFC2253), WOLFSSL_SUCCESS); @@ -557,8 +640,9 @@ int test_wolfSSL_X509_NAME_print_ex(void) ExpectIntEQ(X509_NAME_print_ex(membio, name, 0, XN_FLAG_RFC2253 & ~XN_FLAG_DN_REV), WOLFSSL_SUCCESS); ExpectIntGE((memSz = BIO_get_mem_data(membio, &mem)), 0); - ExpectIntEQ(memSz, XSTRLEN(expEscaped)); - ExpectIntEQ(XSTRNCMP((char*)mem, expEscaped, XSTRLEN(expEscaped)), 0); + ExpectIntEQ(memSz, XSTRLEN(expEscapedComma)); + ExpectIntEQ(XSTRNCMP((char*)mem, expEscapedComma, + XSTRLEN(expEscapedComma)), 0); BIO_free(membio); membio = NULL; diff --git a/wolfssl/openssl/x509.h b/wolfssl/openssl/x509.h index fc30b5818d1..a22a46b4ad6 100644 --- a/wolfssl/openssl/x509.h +++ b/wolfssl/openssl/x509.h @@ -64,6 +64,8 @@ #define WOLFSSL_XN_FLAG_DUMP_UNKNOWN_FIELDS (1 << 24) #define WOLFSSL_XN_FLAG_FN_ALIGN (1 << 25) +/* wolfSSL_X509_NAME_print_ex() flattens multi-valued RDNs: their attributes + * are separated like RDNs, never with '+'. */ #define WOLFSSL_XN_FLAG_RFC2253 (WOLFSSL_ASN1_STRFLGS_RFC2253 | \ WOLFSSL_XN_FLAG_SEP_COMMA_PLUS | \ WOLFSSL_XN_FLAG_DN_REV | \ From 171d4d84e690878c8b703dd7298f0115b2be35c3 Mon Sep 17 00:00:00 2001 From: Juliusz Sosinowicz Date: Tue, 8 Sep 2026 09:38:07 +0000 Subject: [PATCH 5/5] X509_NAME_print_ex: rename misnamed test string expRFC5523 holds the XN_FLAG_RFC2253 expectation. --- tests/api/test_ossl_x509_name.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/tests/api/test_ossl_x509_name.c b/tests/api/test_ossl_x509_name.c index b3a4f2eaa77..2d76fd432b3 100644 --- a/tests/api/test_ossl_x509_name.c +++ b/tests/api/test_ossl_x509_name.c @@ -376,7 +376,7 @@ int test_wolfSSL_X509_NAME_print_ex(void) const char* expNotEscaped = "C= US,+\"\\ , CN=#wolfssl.com<>;"; const char* expNotEscapedRev = "CN=#wolfssl.com<>;, C= US,+\"\\ "; - const char* expRFC5523 = + const char* expRFC2253Esc = "CN=\\#wolfssl.com\\<\\>\\;,C=\\ US\\,\\+\\\"\\\\\\ "; const char* expEscaped = "C=\\ US\\,\\+\\\"\\\\\\ , CN=\\#wolfssl.com\\<\\>\\;"; @@ -605,8 +605,9 @@ int test_wolfSSL_X509_NAME_print_ex(void) ExpectIntEQ(X509_NAME_print_ex(membio, name, 0, XN_FLAG_RFC2253), WOLFSSL_SUCCESS); ExpectIntGE((memSz = BIO_get_mem_data(membio, &mem)), 0); - ExpectIntEQ(memSz, XSTRLEN(expRFC5523)); - ExpectIntEQ(XSTRNCMP((char*)mem, expRFC5523, XSTRLEN(expRFC5523)), 0); + ExpectIntEQ(memSz, XSTRLEN(expRFC2253Esc)); + ExpectIntEQ(XSTRNCMP((char*)mem, expRFC2253Esc, + XSTRLEN(expRFC2253Esc)), 0); BIO_free(membio); membio = NULL;