Clean up the output.
Print out cert chain parsing issues more completely.
This commit is contained in:
relyea%netscape.com 2002-08-16 23:09:02 +00:00
Родитель dc57ad0730
Коммит f9a5a2f1e7
4 изменённых файлов: 156 добавлений и 29 удалений

Просмотреть файл

@ -45,7 +45,7 @@ REQUIRES = seccmd dbm
# DIRS =
CSRCS = vfyserv.c vfyutil.c
DEFINES += -DDLL_PREFIX=\"$(DLL_PREFIX)\" -DDLL_SUFFIX=\"$(DLL_SUFFIX)\" -I../SSLSample
DEFINES += -DDLL_PREFIX=\"$(DLL_PREFIX)\" -DDLL_SUFFIX=\"$(DLL_SUFFIX)\"
PROGRAM = vfyserv

Просмотреть файл

@ -178,7 +178,7 @@ const char requestString[] = {"GET /testfile HTTP/1.0\r\n\r\n" };
SECStatus
handle_connection(PRFileDesc *sslSocket, int connection)
{
int countRead = 0;
int countRead = 0;
PRInt32 numBytes;
char *readBuffer;
@ -210,7 +210,7 @@ handle_connection(PRFileDesc *sslSocket, int connection)
countRead += numBytes;
}
printSecurityInfo(sslSocket);
printSecurityInfo(stderr, sslSocket);
PR_Free(readBuffer);
readBuffer = NULL;
@ -224,6 +224,8 @@ handle_connection(PRFileDesc *sslSocket, int connection)
return SECSuccess; /* success */
}
#define BYTE(n,i) (((i)>>((n)*8))&0xff)
/* one copy of this function is launched in a separate thread for each
** connection to be made.
*/
@ -236,6 +238,7 @@ do_connects(void *a, int connection)
char buffer[PR_NETDB_BUF_SIZE];
PRStatus prStatus;
PRIntn hostenum;
PRInt32 ip;
SECStatus secStatus;
/* Set up SSL secure socket. */
@ -270,8 +273,11 @@ do_connects(void *a, int connection)
return SECFailure;
}
/* printf("Connecting to host %s (addr %d.%d.%d.%d) on port %d\n",
host, hostEntry,port); */
ip = PR_ntohl(addr->inet.ip);
fprintf(stderr,
"Connecting to host %s (addr %d.%d.%d.%d) on port %d\n",
hostName, BYTE(3,ip), BYTE(2,ip), BYTE(1,ip),
BYTE(0,ip), PR_ntohs(addr->inet.port));
prStatus = PR_Connect(sslSocket, addr, PR_INTERVAL_NO_TIMEOUT);
if (prStatus != PR_SUCCESS) {
@ -300,7 +306,8 @@ do_connects(void *a, int connection)
secStatus = handle_connection(sslSocket, connection);
if (secStatus != SECSuccess) {
errWarn("handle_connection");
/* error already printed out in handle_connection */
/* errWarn("handle_connection"); */
return secStatus;
}
@ -356,8 +363,9 @@ client_main(unsigned short port,
int
main(int argc, char **argv)
{
char * certDir = NULL;
char * progName = NULL;
int connections = 1;
int connections = 1;
char * cipherString = NULL;
SECStatus secStatus;
PLOptState * optstate;
@ -374,7 +382,9 @@ main(int argc, char **argv)
switch(optstate->option) {
case 'C' : cipherString = PL_strdup(optstate->value); break;
case 'c' : connections = PORT_Atoi(optstate->value); break;
case 'd' : certDir = PL_strdup(optstate->value); break;
case 'p' : port = PORT_Atoi(optstate->value); break;
case 'w' : password = PL_strdup(optstate->value); break;
case '\0': hostName = PL_strdup(optstate->value); break;
default : Usage(progName);
}
@ -391,20 +401,21 @@ main(int argc, char **argv)
PK11_SetPasswordFunc(myPasswd);
/* Initialize the NSS libraries. */
secStatus = NSS_NoDB_Init(NULL);
if (secStatus != SECSuccess) {
exitErr("Client Error NSS_Init");
}
if (certDir) {
secStatus = NSS_Init(certDir);
} else {
secStatus = NSS_NoDB_Init(NULL);
secStatus = SECMOD_AddNewModule("Builtins",
/* load the builtins */
SECMOD_AddNewModule("Builtins",
DLL_PREFIX"nssckbi."DLL_SUFFIX, 0, 0);
#ifdef notdef
if (secStatus != SECSuccess) {
exitErr("Client Error accessing builtin roots");
}
#endif
if (secStatus != SECSuccess) {
exitErr("NSS_Init");
}
/* All cipher suites except RSA_NULL_MD5 are enabled by Domestic Policy. */
/* All cipher suites except RSA_NULL_MD5 are enabled by
* Domestic Policy. */
NSS_SetDomesticPolicy();
SSL_CipherPrefSetDefault(SSL_RSA_WITH_NULL_MD5, PR_TRUE);

Просмотреть файл

@ -107,7 +107,11 @@ void errWarn(char *function);
void exitErr(char *function);
void printSecurityInfo(PRFileDesc *fd);
void printSecurityInfo(FILE *outfile, PRFileDesc *fd);
void printCertProblems(FILE *outfile, CERTCertDBHandle *handle,
CERTCertificate *cert, PRBool checksig,
SECCertUsage certUsage, void *pinArg);
/* Some simple thread management routines. */

Просмотреть файл

@ -32,7 +32,10 @@
*/
#include "vfyserv.h"
#include "sslerror.h" /* go find the real one in libutil! */
#include "secerr.h"
#include "sslerr.h"
#include "nspr.h"
#include "secutil.h"
/* Declare SSL cipher suites. */
@ -127,6 +130,8 @@ myAuthCertificate(void *arg, PRFileDesc *socket,
/* If this is a server, we're finished. */
if (isServer || secStatus != SECSuccess) {
printCertProblems(stderr, (CERTCertDBHandle *)arg, cert,
checksig, certUsage, pinArg);
CERT_DestroyCertificate(cert);
return secStatus;
}
@ -204,7 +209,7 @@ myBadCertHandler(void *arg, PRFileDesc *socket)
break;
}
printf("Bad certificate: %d, %s\n", err, SSL_Strerror(err));
fprintf(stderr, "Bad certificate: %d, %s\n", err, SECU_Strerror(err));
return secStatus;
}
@ -311,7 +316,7 @@ myGetClientAuthData(void *arg,
SECStatus
myHandshakeCallback(PRFileDesc *socket, void *arg)
{
printf("Handshake has completed, ready to send data securely.\n");
fprintf(stderr,"Handshake Complete: SERVER CONFIGURED CORRECTLY\n");
return SECSuccess;
}
@ -334,7 +339,8 @@ disableAllSSLCiphers(void)
PRUint16 suite = cipherSuites[i];
rv = SSL_CipherPrefSetDefault(suite, PR_FALSE);
if (rv != SECSuccess) {
printf("SSL_CipherPrefSetDefault didn't like value 0x%04x (i = %d)\n",
fprintf(stderr,
"SSL_CipherPrefSetDefault didn't like value 0x%04x (i = %d)\n",
suite, i);
errWarn("SSL_CipherPrefSetDefault");
exit(2);
@ -352,9 +358,9 @@ void
errWarn(char *function)
{
PRErrorCode errorNumber = PR_GetError();
const char * errorString = SSL_Strerror(errorNumber);
const char * errorString = SECU_Strerror(errorNumber);
printf("Error in function %s: %d\n - %s\n",
fprintf(stderr, "Error in function %s: %d\n - %s\n",
function, errorNumber, errorString);
}
@ -369,7 +375,7 @@ exitErr(char *function)
}
void
printSecurityInfo(PRFileDesc *fd)
printSecurityInfo(FILE *outfile, PRFileDesc *fd)
{
char * cp; /* bulk cipher name */
char * ip; /* cert issuer DN */
@ -380,17 +386,23 @@ printSecurityInfo(PRFileDesc *fd)
int result;
SSL3Statistics * ssl3stats = SSL_GetStatistics();
if (!outfile) {
outfile = stdout;
}
result = SSL_SecurityStatus(fd, &op, &cp, &kp0, &kp1, &ip, &sp);
if (result != SECSuccess)
return;
printf("bulk cipher %s, %d secret key bits, %d key bits, status: %d\n"
"subject DN: %s\n"
"issuer DN: %s\n", cp, kp1, kp0, op, sp, ip);
fprintf(outfile,
" bulk cipher %s, %d secret key bits, %d key bits, status: %d\n"
" subject DN:\n %s\n"
" issuer DN:\n %s\n", cp, kp1, kp0, op, sp, ip);
PR_Free(cp);
PR_Free(ip);
PR_Free(sp);
printf("%ld cache hits; %ld cache misses, %ld cache not reusable\n",
fprintf(outfile,
" %ld cache hits; %ld cache misses, %ld cache not reusable\n",
ssl3stats->hch_sid_cache_hits, ssl3stats->hch_sid_cache_misses,
ssl3stats->hch_sid_cache_not_ok);
@ -586,3 +598,103 @@ lockedVars_AddToCount(lockedVars * lv, int addend)
PR_Unlock(lv->lock);
return rv;
}
static char *
bestCertName(CERTCertificate *cert) {
if (cert->nickname) {
return cert->nickname;
}
if (cert->emailAddr) {
return cert->emailAddr;
}
return cert->subjectName;
}
void
printCertProblems(FILE *outfile, CERTCertDBHandle *handle,
CERTCertificate *cert, PRBool checksig,
SECCertUsage certUsage, void *pinArg)
{
CERTVerifyLog log;
CERTVerifyLogNode *node = NULL;
unsigned int depth = (unsigned int)-1;
unsigned int flags = 0;
char *errstr = NULL;
log.arena = PORT_NewArena(512);
log.head = log.tail = NULL;
log.count = 0;
CERT_VerifyCert(handle, cert, checksig, certUsage,
PR_Now(), pinArg, &log);
if (log.count > 0) {
fprintf(outfile,"PROBLEM WITH THE CERT CHAIN:\n");
for (node = log.head; node; node = node->next) {
if (depth != node->depth) {
depth = node->depth;
fprintf(outfile,"CERT %d. %s %s:\n", depth,
bestCertName(node->cert),
depth ? "[Certificate Authority]": "");
}
fprintf(outfile," ERROR %d: %s\n", node->error,
SECU_Strerror(node->error));
errstr = NULL;
switch (node->error) {
case SEC_ERROR_INADEQUATE_KEY_USAGE:
flags = (unsigned int)node->arg;
switch (flags) {
case KU_DIGITAL_SIGNATURE:
errstr = "Cert cannot sign.";
break;
case KU_KEY_ENCIPHERMENT:
errstr = "Cert cannot encrypt.";
break;
case KU_KEY_CERT_SIGN:
errstr = "Cert cannot sign other certs.";
break;
default:
errstr = "[unknown usage].";
break;
}
case SEC_ERROR_INADEQUATE_CERT_TYPE:
flags = (unsigned int)node->arg;
switch (flags) {
case NS_CERT_TYPE_SSL_CLIENT:
case NS_CERT_TYPE_SSL_SERVER:
errstr = "Cert cannot be used for SSL.";
break;
case NS_CERT_TYPE_SSL_CA:
errstr = "Cert cannot be used as an SSL CA.";
break;
case NS_CERT_TYPE_EMAIL:
errstr = "Cert cannot be used for SMIME.";
break;
case NS_CERT_TYPE_EMAIL_CA:
errstr = "Cert cannot be used as an SMIME CA.";
break;
case NS_CERT_TYPE_OBJECT_SIGNING:
errstr = "Cert cannot be used for object signing.";
break;
case NS_CERT_TYPE_OBJECT_SIGNING_CA:
errstr = "Cert cannot be used as an object signing CA.";
break;
default:
errstr = "[unknown usage].";
break;
}
case SEC_ERROR_UNKNOWN_ISSUER:
case SEC_ERROR_UNTRUSTED_ISSUER:
case SEC_ERROR_EXPIRED_ISSUER_CERTIFICATE:
errstr = node->cert->issuerName;
break;
default:
break;
}
if (errstr) {
fprintf(stderr," %s\n",errstr);
}
CERT_DestroyCertificate(node->cert);
}
}
return ;
}