Sorted output for certutil -L smimetk_branch
authorchrisk%netscape.com
Mon, 12 Jun 2000 22:18:58 +0000
branchsmimetk_branch
changeset 356 761ff0bd75415f1b7088144bcc2c7dad53f74f4c
parent 353 ef765a69e74f39d5d25f3e87af12c45197b13717
child 359 d2cafc99bbc3f6f1610aeaba89e227c1b343fe07
push idunknown
push userunknown
push dateunknown
Sorted output for certutil -L
security/nss/cmd/certutil/certutil.c
security/nss/cmd/lib/secutil.c
--- a/security/nss/cmd/certutil/certutil.c
+++ b/security/nss/cmd/certutil/certutil.c
@@ -565,20 +565,21 @@ static SECStatus
 ListCerts(CERTCertDBHandle *handle, char *name, PRBool raw, PRBool ascii)
 {
     SECStatus rv;
     CERTCertificate *cert;
     SECItem data;
     PRInt32 numBytes;
 
     if (name == NULL) {
-	/*
-	SECU_PrintCertificateNames_(PR_STDOUT, PR_TRUE, PR_FALSE);
-	*/
+#if 1
+	rv = SECU_PrintCertificateNames_(handle, stdout, PR_FALSE, PR_TRUE);
+#else
 	rv = SECU_PrintCertificateNames(handle, stdout);
+#endif
 	if (rv) {
 	    SECU_PrintError(progName, "problem printing certificate nicknames");
 	    return SECFailure;
 	}
     } else if (raw || ascii) {
 	cert = CERT_FindCertByNicknameOrEmailAddr(handle, name);
 	if (!cert) {
 	    SECU_PrintError(progName,
@@ -922,21 +923,22 @@ Usage(char *progName)
     FPS "\t%s -S -n cert-name -s subj [-c issuer-name | -x]  -t trustargs\n"
 	"\t\t [-k key-type] [-h token-name] [-g key-size]\n"
         "\t\t [-m serial-number] [-w warp-months] [-v months-valid]\n"
 	"\t\t [-f pwfile] [-d certdir]\n"
         "\t\t [-p phone] [-1] [-2] [-3] [-4] [-5] [-6]\n",
 	progName);
     FPS "\t%s -U [-d certdir]\n", progName);
     exit(-1);
+#undef FPS
 }
 
 static void LongUsage(char *progName)
 {
-
+#define FPS printf( 
     FPS "%-15s Add a certificate to the database        (create if needed)\n",
 	"-A");
     FPS "%-15s Add an Email certificate to the database (create if needed)\n",
 	"-E");
     FPS "%-20s Specify the nickname of the certificate to add\n",
 	"   -n cert-name");
     FPS "%-20s Set the certificate trust attributes:\n",
 	"   -t trustargs");
--- a/security/nss/cmd/lib/secutil.c
+++ b/security/nss/cmd/lib/secutil.c
@@ -2012,82 +2012,152 @@ secu_PrintCertNickname(CERTCertificate *
 	PORT_Strcat(trusts, ",");
 	printflags(trusts, trust->objectSigningFlags);
 	fprintf(out, "%-35s %-5s\n", name, trusts);
     }
 
     return (SECSuccess);
 }
 
-#if 0
+#if 1
+typedef struct {
+    char *		name;
+    CERTCertTrust	trust;
+} certNameAndTrustEntry;
+
 typedef struct {
     int numCerts;
-    struct {
-	char *names;
-	CERTCertTrust trusts;
-    } *nameAndTrustEntry;
+    certNameAndTrustEntry *nameAndTrustEntries;
 } certNameAndTrustList;
 
 SECStatus
 sec_CountCerts(CERTCertificate *cert, SECItem *unknown, void *arg)
 {
     (*(int*)arg)++;
     return SECSuccess;
 }
 
 SECStatus
 sec_CollectCertNamesAndTrust(CERTCertificate *cert, SECItem *unknown, void *arg)
 {
-    certNameAndTrustList *certNames = (certNameAndTrustList*)arg;
+    certNameAndTrustList *pCertNames = (certNameAndTrustList*)arg;
     char *name;
-    int i = certNames->numCerts;
-
-    name = cert->dbEntry->nickname;
-    if ( name == NULL ) {
-	name = cert->emailAddr;
-    }
-
-    certNames->names[i] = PORT_Strdup(name);
-
-    PORT_Memcpy(&certNames->trusts[i], cert->trust, sizeof(*cert->trust));
-
-    certNames->numCerts++;
+    int i;
+
+    i = pCertNames->numCerts;
+    name = cert->dbEntry->nickname ? cert->dbEntry->nickname : cert->emailAddr;
+
+    if (name)
+	pCertNames->nameAndTrustEntries[i].name = PORT_Strdup(name);
+    else
+	pCertNames->nameAndTrustEntries[i].name = PORT_Strdup("<unknown>");
+
+    PORT_Memcpy(&pCertNames->nameAndTrustEntries[i].trust, cert->trust, sizeof(*cert->trust));
+
+    pCertNames->numCerts++;
 
     return SECSuccess;
 }
 
+static int
+sec_name_and_trust_compare_by_name(const void *p1, const void *p2)
+{
+    certNameAndTrustEntry *e1 = (certNameAndTrustEntry *)p1;
+    certNameAndTrustEntry *e2 = (certNameAndTrustEntry *)p2;
+    return PORT_Strcmp(e1->name, e2->name);
+}
+
+static int
+sec_combine_trust_flags(CERTCertTrust *trust)
+{
+    if (trust == NULL)
+	return NULL;
+    return trust->sslFlags | trust->emailFlags | trust->objectSigningFlags;
+}
+
+static int
+sec_name_and_trust_compare_by_trust(const void *p1, const void *p2)
+{
+    certNameAndTrustEntry *e1 = (certNameAndTrustEntry *)p1;
+    certNameAndTrustEntry *e2 = (certNameAndTrustEntry *)p2;
+    int e1_is_ca, e2_is_ca;
+    int e1_is_user, e2_is_user;
+    int rv;
+
+    e1_is_ca = (sec_combine_trust_flags(&e1->trust) & CERTDB_VALID_CA) != 0;
+    e2_is_ca = (sec_combine_trust_flags(&e2->trust) & CERTDB_VALID_CA) != 0;
+    e1_is_user = (sec_combine_trust_flags(&e1->trust) & CERTDB_USER) != 0;
+    e2_is_user = (sec_combine_trust_flags(&e2->trust) & CERTDB_USER) != 0;
+
+    /* first, sort by user status, then CA status, */
+    /*  then by actual comparison of CA flags, then by name */
+    if ((rv = (e2_is_user - e1_is_user)) == 0 && (rv = (e1_is_ca - e2_is_ca)) == 0)
+	if (e1_is_ca || (rv = memcmp(&e1->trust, &e2->trust, sizeof(CERTCertTrust))) == 0)
+	    return PORT_Strcmp(e1->name, e2->name);
+	else
+	    return rv;
+    else
+	return rv;
+}
+
 SECStatus
-SECU_PrintCertificateNames_(PRFileDesc* out, PRBool sortByName, 
+SECU_PrintCertificateNames_(CERTCertDBHandle *handle, FILE *out, PRBool sortByName, 
                             PRBool sortByTrust)
 {
-    int numCerts;
-    certNameAndTrustList certNames = { 0, 0, 0 };
+    certNameAndTrustList certNames = { 0, NULL };
+    int numCerts, i;
     SECStatus rv;
-
-    CERTCertDBHandle *handle = CERT_GetDefaultCertDB();
+    int (*comparefn)(const void *, const void *);
+    char trusts[30];
 
     numCerts = 0;
 
     rv = SEC_TraversePermCerts(handle, sec_CountCerts, &numCerts);
-    certNames.names = (char**)PORT_Alloc(numCerts*sizeof(char*));
-    certNames.trusts = 
-       (CERTCertTrust*)PORT_Alloc(numCerts*sizeof(CERTCertTrust));
-    rv = SEC_TraversePermCerts(handle, 
-                               sec_CollectCertNamesAndTrust, &certNames);
-
-    /*
+    if (rv != SECSuccess)
+	return SECFailure;
+
+    certNames.nameAndTrustEntries = 
+		(certNameAndTrustEntry *)PORT_Alloc(numCerts * sizeof(certNameAndTrustEntry));
+    if (certNames.nameAndTrustEntries == NULL)
+	return SECFailure;
+
+    rv = SEC_TraversePermCerts(handle, sec_CollectCertNamesAndTrust, &certNames);
+    if (rv != SECSuccess)
+	return SECFailure;
+
+#if 0
     rv = PK11_TraverseSlotCerts(sec_CountCerts, &numCerts, NULL);
     certs = (CERTCertificate**)PORT_Alloc(numCerts*sizeof(CERTCertificate*));
     rv = PK11_TraverseSlotCerts(sec_CollectCerts, certs, NULL);
-    */
-
-    qsort();
-
-    PORT_Free(certNames.names);
-    PORT_Free(certNames.trusts);
+#endif
+
+    if (sortByName)
+	comparefn = sec_name_and_trust_compare_by_name;
+    else if (sortByTrust)
+	comparefn = sec_name_and_trust_compare_by_trust;
+    else
+	comparefn = NULL;
+
+    if (comparefn)
+	qsort(certNames.nameAndTrustEntries, certNames.numCerts, 
+			    sizeof(certNameAndTrustEntry), comparefn);
+
+    for (i = 0; i < certNames.numCerts; i++) {
+	PORT_Memset (trusts, 0, sizeof(trusts));
+	printflags(trusts, certNames.nameAndTrustEntries[i].trust.sslFlags);
+	PORT_Strcat(trusts, ",");
+	printflags(trusts, certNames.nameAndTrustEntries[i].trust.emailFlags);
+	PORT_Strcat(trusts, ",");
+	printflags(trusts, certNames.nameAndTrustEntries[i].trust.objectSigningFlags);
+	fprintf(out, "%-60s %-5s\n", certNames.nameAndTrustEntries[i].name, trusts);
+    }
+
+    for (i = 0; i < certNames.numCerts; i++)
+	PORT_Free(certNames.nameAndTrustEntries[i].name);
+    PORT_Free(certNames.nameAndTrustEntries);
 
     return rv;
 }
 #endif
 
 int
 SECU_PrintCertificateNames(CERTCertDBHandle *handle, FILE *out)
 {