changeset: 6876:1a2dc7b21b5b user: Kevin McCarthy <ke...@8t8.us> date: Tue Nov 29 17:44:31 2016 -0800 link: http://dev.mutt.org/hg/mutt/rev/1a2dc7b21b5b
Improve openssl interactive_check_cert. (closes #3899) Don't use X509_NAME_oneline() with a fixed size buffer, which could truncate the string, perhaps leaving off the CN field entirely. Instead, work directly off the X509_NAME. Rather than use strstr to tokenize it, call X509_NAME_get_text_by_NID() with the nid types. Although X509_NAME_get_text_by_NID() is "legacy", it is the most directly useful for mutt in this simple interactive prompt. The function was set up to include the ST and C fields in the prompt, but the loop limit was too low. I believe this was an oversight, so increase the loop to include those two fields. changeset: 6877:1196c859942e user: Kevin McCarthy <ke...@8t8.us> date: Tue Nov 29 17:44:37 2016 -0800 link: http://dev.mutt.org/hg/mutt/rev/1196c859942e Add mutt_array_size macro, change interactive_check_cert() to use it. (see #3899) While I have reservations about the construct, it does make the interactive_check_cert() menu->max and part loop less fragile. diffs (109 lines): diff -r 84ad86e8b8ab -r 1196c859942e lib.h --- a/lib.h Sat Nov 26 00:57:42 2016 +0100 +++ b/lib.h Tue Nov 29 17:44:37 2016 -0800 @@ -84,6 +84,10 @@ # define MAX(a,b) ((a) < (b) ? (b) : (a)) # define MIN(a,b) ((a) < (b) ? (a) : (b)) +/* Use this with care. If the compiler can't see the array + * definition, it obviously won't produce a correct result. */ +#define mutt_array_size(x) (sizeof (x) / sizeof ((x)[0])) + /* For mutt_format_string() justifications */ /* Making left 0 and center -1 is of course completely nonsensical, but * it retains compatibility for any patches that call mutt_format_string. diff -r 84ad86e8b8ab -r 1196c859942e mutt_ssl.c --- a/mutt_ssl.c Sat Nov 26 00:57:42 2016 +0100 +++ b/mutt_ssl.c Tue Nov 29 17:44:37 2016 -0800 @@ -558,24 +558,13 @@ } -static char *x509_get_part (char *line, const char *ndx) +static char *x509_get_part (X509_NAME *name, int nid) { static char ret[SHORT_STRING]; - char *c, *c2; - strfcpy (ret, _("Unknown"), sizeof (ret)); - - c = strstr (line, ndx); - if (c) - { - c += strlen (ndx); - c2 = strchr (c, '/'); - if (c2) - *c2 = '\0'; - strfcpy (ret, c, sizeof (ret)); - if (c2) - *c2 = '/'; - } + if (!name || + X509_NAME_get_text_by_NID (name, nid, ret, sizeof (ret)) < 0) + strfcpy (ret, _("Unknown"), sizeof (ret)); return ret; } @@ -1011,17 +1000,24 @@ static int interactive_check_cert (X509 *cert, int idx, int len) { - static const char * const part[] = - {"/CN=", "/Email=", "/O=", "/OU=", "/L=", "/ST=", "/C="}; + static const int part[] = + { NID_commonName, /* CN */ + NID_pkcs9_emailAddress, /* Email */ + NID_organizationName, /* O */ + NID_organizationalUnitName, /* OU */ + NID_localityName, /* L */ + NID_stateOrProvinceName, /* ST */ + NID_countryName /* C */ }; + X509_NAME *x509_subject; + X509_NAME *x509_issuer; char helpstr[LONG_STRING]; char buf[STRING]; char title[STRING]; MUTTMENU *menu = mutt_new_menu (MENU_GENERIC); int done, row, i; FILE *fp; - char *name = NULL, *c; - menu->max = 19; + menu->max = mutt_array_size (part) * 2 + 9; menu->dialog = (char **) safe_calloc (1, menu->max * sizeof (char *)); for (i = 0; i < menu->max; i++) menu->dialog[i] = (char *) safe_calloc (1, SHORT_STRING * sizeof (char)); @@ -1029,25 +1025,18 @@ row = 0; strfcpy (menu->dialog[row], _("This certificate belongs to:"), SHORT_STRING); row++; - name = X509_NAME_oneline (X509_get_subject_name (cert), - buf, sizeof (buf)); - - for (i = 0; i < 5; i++) - { - c = x509_get_part (name, part[i]); - snprintf (menu->dialog[row++], SHORT_STRING, " %s", c); - } + x509_subject = X509_get_subject_name (cert); + for (i = 0; i < mutt_array_size (part); i++) + snprintf (menu->dialog[row++], SHORT_STRING, " %s", + x509_get_part (x509_subject, part[i])); row++; strfcpy (menu->dialog[row], _("This certificate was issued by:"), SHORT_STRING); row++; - name = X509_NAME_oneline (X509_get_issuer_name (cert), - buf, sizeof (buf)); - for (i = 0; i < 5; i++) - { - c = x509_get_part (name, part[i]); - snprintf (menu->dialog[row++], SHORT_STRING, " %s", c); - } + x509_issuer = X509_get_issuer_name (cert); + for (i = 0; i < mutt_array_size (part); i++) + snprintf (menu->dialog[row++], SHORT_STRING, " %s", + x509_get_part (x509_issuer, part[i])); row++; snprintf (menu->dialog[row++], SHORT_STRING, _("This certificate is valid"));