X509_NAME_oneline(): Fix output of multi-valued RDNs, escaping '/' and '+' in values

Reviewed-by: Tomas Mraz <tmraz@fedoraproject.org>
(Merged from https://github.com/openssl/openssl/pull/12769)
This commit is contained in:
Dr. David von Oheimb 2020-09-02 14:18:34 +02:00
parent 115786793c
commit 2aa91df406
2 changed files with 28 additions and 21 deletions

View File

@ -13,6 +13,7 @@
#include <openssl/x509.h>
#include <openssl/buffer.h>
#include "crypto/x509.h"
#include "crypto/ctype.h"
DEFINE_STACK_OF(X509_NAME_ENTRY)
@ -28,6 +29,7 @@ char *X509_NAME_oneline(const X509_NAME *a, char *buf, int len)
const X509_NAME_ENTRY *ne;
int i;
int n, lold, l, l1, l2, num, j, type;
int prev_set = -1;
const char *s;
char *p;
unsigned char *q;
@ -109,14 +111,11 @@ char *X509_NAME_oneline(const X509_NAME *a, char *buf, int len)
if (!gs_doit[j & 3])
continue;
l2++;
#ifndef CHARSET_EBCDIC
if ((q[j] < ' ') || (q[j] > '~'))
if (q[j] == '/' || q[j] == '+')
l2++; /* char needs to be escaped */
else if ((ossl_toascii(q[j]) < ossl_toascii(' ')) ||
(ossl_toascii(q[j]) > ossl_toascii('~')))
l2 += 3;
#else
if ((os_toascii[q[j]] < os_toascii[' ']) ||
(os_toascii[q[j]] > os_toascii['~']))
l2 += 3;
#endif
}
lold = l;
@ -133,7 +132,7 @@ char *X509_NAME_oneline(const X509_NAME *a, char *buf, int len)
break;
} else
p = &(buf[lold]);
*(p++) = '/';
*(p++) = prev_set == ne->set ? '+' : '/';
memcpy(p, s, (unsigned int)l1);
p += l1;
*(p++) = '=';
@ -152,8 +151,11 @@ char *X509_NAME_oneline(const X509_NAME *a, char *buf, int len)
*(p++) = 'x';
*(p++) = hex[(n >> 4) & 0x0f];
*(p++) = hex[n & 0x0f];
} else
} else {
if (n == '/' || n == '+')
*(p++) = '\\';
*(p++) = n;
}
#else
n = os_toascii[q[j]];
if ((n < os_toascii[' ']) || (n > os_toascii['~'])) {
@ -161,11 +163,15 @@ char *X509_NAME_oneline(const X509_NAME *a, char *buf, int len)
*(p++) = 'x';
*(p++) = hex[(n >> 4) & 0x0f];
*(p++) = hex[n & 0x0f];
} else
} else {
if (n == os_toascii['/'] || n == os_toascii['+'])
*(p++) = '\\';
*(p++) = q[j];
}
#endif
}
*p = '\0';
prev_set = ne->set;
}
if (b != NULL) {
p = b->data;

View File

@ -18,27 +18,28 @@ X509_NAME_oneline - X509_NAME printing routines
=head1 DESCRIPTION
X509_NAME_print_ex() prints a human readable version of B<nm> to BIO B<out>.
Each line (for multiline formats) is indented by B<indent> spaces. The
output format can be extensively customised by use of the B<flags> parameter.
X509_NAME_print_ex() prints a human readable version of I<nm> to BIO I<out>.
Each line (for multiline formats) is indented by I<indent> spaces. The
output format can be extensively customised by use of the I<flags> parameter.
X509_NAME_print_ex_fp() is identical to X509_NAME_print_ex()
except the output is written to FILE pointer B<fp>.
except the output is written to FILE pointer I<fp>.
X509_NAME_oneline() prints an ASCII version of B<a> to B<buf>.
If B<buf> is B<NULL> then a buffer is dynamically allocated and returned, and
B<size> is ignored.
Otherwise, at most B<size> bytes will be written, including the ending '\0',
and B<buf> is returned.
X509_NAME_oneline() prints an ASCII version of I<a> to I<buf>.
This supports multi-valued RDNs and escapes B</> and B<+> characters in values.
If I<buf> is B<NULL> then a buffer is dynamically allocated and returned, and
I<size> is ignored.
Otherwise, at most I<size> bytes will be written, including the ending '\0',
and I<buf> is returned.
X509_NAME_print() prints out B<name> to B<bp> indenting each line by B<obase>
X509_NAME_print() prints out I<name> to I<bp> indenting each line by I<obase>
characters. Multiple lines are used if the output (including indent) exceeds
80 characters.
=head1 NOTES
The functions X509_NAME_oneline() and X509_NAME_print()
produce a non standard output form, they don't handle multi character fields and
produce a non standard output form, they don't handle multi-character fields and
have various quirks and inconsistencies.
Their use is strongly discouraged in new applications and they could
be deprecated in a future release.