[tin-dev] [PATCH] USE_OPENSSL and cert (subject/issuer) with umlauts
Dennis Preiser
dennis at d--p.de
Wed Dec 6 16:43:34 CET 2023
Hi there,
at least with OpenSSL the current code doesn't handle umlauts in
certificates (subject/issuer) very well in case of
defined(MULTIBYTE_ABLE) && !defined(NO_LOCALE) (startup messages and
ConnectionInfo 'J'). Umlauts are displayed somehow raw.
Here is how it currently looks like (news.individual.de):
| Subject: /C=DE/ST=Berlin/O=Freie Universit\xC3\xA4t Berlin/CN=news.individual.de
^^^^^^^^
| Issuer : /C=GB/ST=Greater Manchester/L=Salford/O=Sectigo Limited/CN=Sectigo RSA Organization
I'm not sure whether it's worth the effort in this respect, but the
attached patch changes the behaviour so that at least with
defined(MULTIBYTE_ABLE) && !defined(NO_LOCALE) umlauts are displayed
correctly. The whole output also looks a little more elegant.
Here is the defined(MULTIBYTE_ABLE) && !defined(NO_LOCALE) case:
| Subject: C=DE, ST=Berlin, O=Freie Universität Berlin, CN=news.individual.de
| Issuer : C=GB, ST=Greater Manchester, L=Salford, O=Sectigo Limited, CN=Sectigo RSA Organization
and here the !(defined(MULTIBYTE_ABLE) && !defined(NO_LOCALE)) case:
| Subject: C=DE, ST=Berlin, O=Freie Universit\C3\A4t Berlin, CN=news.individual.de
| Issuer : C=GB, ST=Greater Manchester, L=Salford, O=Sectigo Limited, CN=Sectigo RSA Organization
As I only have OpenSSL available, I cannot say whether this is the case
with the other variants. The patch only affects the OpenSSL case.
Dennis
-------------- next part --------------
--- a/src/nntps.c
+++ b/src/nntps.c
@@ -47,6 +47,7 @@ static void log_func(int level, const char *msg);
# endif /* DEBUG */
#else
# ifdef USE_OPENSSL
+static char **get_cert_info(const X509 *cert);
# ifdef DEBUG
static void info_callback(const SSL *s, int where, int ret);
# endif /* DEBUG */
@@ -533,7 +534,6 @@ err_cert:
BIO *client = session_ctx;
SSL *ssl;
X509 *peer;
- char name[128];
ERR_clear_error();
@@ -561,8 +561,15 @@ err_cert:
peer = SSL_get_peer_certificate(ssl);
if (peer) {
if (!batch_mode || verbose) {
- wait_message(0, _(txt_conninfo_subject), X509_NAME_oneline(X509_get_subject_name(peer), name, sizeof(name)));
- wait_message(0, _(txt_conninfo_issuer), X509_NAME_oneline(X509_get_issuer_name(peer), name, sizeof(name)));
+ char **cert_info;
+
+ if ((cert_info = get_cert_info(peer))) {
+ wait_message(0, _(txt_conninfo_subject), BlankIfNull(cert_info[0]));
+ wait_message(0, _(txt_conninfo_issuer), BlankIfNull(cert_info[1]));
+ FreeIfNeeded(cert_info[0]);
+ FreeIfNeeded(cert_info[1]);
+ free(cert_info);
+ }
}
X509_free(peer);
}
@@ -899,6 +906,7 @@ err_cert:
if (chain) {
char name[128];
+ char **cert_info;
const ASN1_TIME *asn1;
int i;
struct tm tm;
@@ -909,8 +917,14 @@ err_cert:
if (i > 0)
fputs("\n", fp);
fprintf(fp, _(txt_conninfo_cert), i);
- fprintf(fp, _(txt_conninfo_subject), X509_NAME_oneline(X509_get_subject_name(cert), name, sizeof(name)));
- fprintf(fp, _(txt_conninfo_issuer), X509_NAME_oneline(X509_get_issuer_name(cert), name, sizeof(name)));
+
+ if ((cert_info = get_cert_info(cert))) {
+ fprintf(fp, _(txt_conninfo_subject), BlankIfNull(cert_info[0]));
+ fprintf(fp, _(txt_conninfo_issuer), BlankIfNull(cert_info[1]));
+ FreeIfNeeded(cert_info[0]);
+ FreeIfNeeded(cert_info[1]);
+ free(cert_info);
+ }
asn1 = X509_get0_notBefore(cert);
result = ASN1_TIME_to_tm(asn1, &tm);
@@ -937,6 +951,46 @@ err_cert:
#ifdef USE_OPENSSL
+static char **
+get_cert_info(
+ const X509 *cert)
+{
+ BIO *io_buf;
+ char **res = NULL;
+ char *tmp, *subject = NULL, *issuer = NULL;
+ long len;
+#if defined(MULTIBYTE_ABLE) && !defined(NO_LOCALE)
+ unsigned long flags = XN_FLAG_ONELINE & ~ASN1_STRFLGS_ESC_MSB & ~XN_FLAG_SPC_EQ;
+#else
+ unsigned long flags = XN_FLAG_ONELINE & ~XN_FLAG_SPC_EQ;
+#endif /* MULTIBYTE_ABLE && !NO_LOCALE */
+
+ if (cert && (io_buf = BIO_new(BIO_s_mem()))) {
+ res = my_malloc(sizeof(char *) * 2);
+ if (X509_NAME_print_ex(io_buf, X509_get_subject_name(cert), 0, flags) != -1) {
+ len = BIO_get_mem_data(io_buf, &tmp);
+ if (len > 0) {
+ subject = my_malloc((size_t) len + 1);
+ memcpy(subject, tmp, len);
+ subject[len] = '\0';
+ }
+ }
+ if (BIO_reset(io_buf) != -1 && X509_NAME_print_ex(io_buf, X509_get_issuer_name(cert), 0, flags) != -1) {
+ len = BIO_get_mem_data(io_buf, &tmp);
+ if (len > 0) {
+ issuer = my_malloc((size_t) len + 1);
+ memcpy(issuer, tmp, len);
+ issuer[len] = '\0';
+ }
+ }
+ res[0] = subject;
+ res[1] = issuer;
+ BIO_free(io_buf);
+ }
+ return res;
+}
+
+
static void
show_errors(
const char *msg_fmt)
More information about the tin-dev
mailing list