mutt stable branch with some hacks

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.

+23 -34
+23 -34
mutt_ssl.c
··· 558 558 } 559 559 560 560 561 - static char *x509_get_part (char *line, const char *ndx) 561 + static char *x509_get_part (X509_NAME *name, int nid) 562 562 { 563 563 static char ret[SHORT_STRING]; 564 - char *c, *c2; 565 - 566 - strfcpy (ret, _("Unknown"), sizeof (ret)); 567 564 568 - c = strstr (line, ndx); 569 - if (c) 570 - { 571 - c += strlen (ndx); 572 - c2 = strchr (c, '/'); 573 - if (c2) 574 - *c2 = '\0'; 575 - strfcpy (ret, c, sizeof (ret)); 576 - if (c2) 577 - *c2 = '/'; 578 - } 565 + if (!name || 566 + X509_NAME_get_text_by_NID (name, nid, ret, sizeof (ret)) < 0) 567 + strfcpy (ret, _("Unknown"), sizeof (ret)); 579 568 580 569 return ret; 581 570 } ··· 1011 1000 1012 1001 static int interactive_check_cert (X509 *cert, int idx, int len) 1013 1002 { 1014 - static const char * const part[] = 1015 - {"/CN=", "/Email=", "/O=", "/OU=", "/L=", "/ST=", "/C="}; 1003 + static const int part[] = 1004 + { NID_commonName, /* CN */ 1005 + NID_pkcs9_emailAddress, /* Email */ 1006 + NID_organizationName, /* O */ 1007 + NID_organizationalUnitName, /* OU */ 1008 + NID_localityName, /* L */ 1009 + NID_stateOrProvinceName, /* ST */ 1010 + NID_countryName /* C */ }; 1011 + X509_NAME *x509_subject; 1012 + X509_NAME *x509_issuer; 1016 1013 char helpstr[LONG_STRING]; 1017 1014 char buf[STRING]; 1018 1015 char title[STRING]; 1019 1016 MUTTMENU *menu = mutt_new_menu (MENU_GENERIC); 1020 1017 int done, row, i; 1021 1018 FILE *fp; 1022 - char *name = NULL, *c; 1023 1019 1024 - menu->max = 19; 1020 + menu->max = 23; 1025 1021 menu->dialog = (char **) safe_calloc (1, menu->max * sizeof (char *)); 1026 1022 for (i = 0; i < menu->max; i++) 1027 1023 menu->dialog[i] = (char *) safe_calloc (1, SHORT_STRING * sizeof (char)); ··· 1029 1025 row = 0; 1030 1026 strfcpy (menu->dialog[row], _("This certificate belongs to:"), SHORT_STRING); 1031 1027 row++; 1032 - name = X509_NAME_oneline (X509_get_subject_name (cert), 1033 - buf, sizeof (buf)); 1034 - 1035 - for (i = 0; i < 5; i++) 1036 - { 1037 - c = x509_get_part (name, part[i]); 1038 - snprintf (menu->dialog[row++], SHORT_STRING, " %s", c); 1039 - } 1028 + x509_subject = X509_get_subject_name (cert); 1029 + for (i = 0; i < 7; i++) 1030 + snprintf (menu->dialog[row++], SHORT_STRING, " %s", 1031 + x509_get_part (x509_subject, part[i])); 1040 1032 1041 1033 row++; 1042 1034 strfcpy (menu->dialog[row], _("This certificate was issued by:"), SHORT_STRING); 1043 1035 row++; 1044 - name = X509_NAME_oneline (X509_get_issuer_name (cert), 1045 - buf, sizeof (buf)); 1046 - for (i = 0; i < 5; i++) 1047 - { 1048 - c = x509_get_part (name, part[i]); 1049 - snprintf (menu->dialog[row++], SHORT_STRING, " %s", c); 1050 - } 1036 + x509_issuer = X509_get_issuer_name (cert); 1037 + for (i = 0; i < 7; i++) 1038 + snprintf (menu->dialog[row++], SHORT_STRING, " %s", 1039 + x509_get_part (x509_issuer, part[i])); 1051 1040 1052 1041 row++; 1053 1042 snprintf (menu->dialog[row++], SHORT_STRING, _("This certificate is valid"));