mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-02-16 22:04:36 +00:00
use error code in secutil.
Clean up the output. Print out cert chain parsing issues more completely.
This commit is contained in:
parent
a1ba18b687
commit
bb6cf23f23
@ -45,7 +45,7 @@ REQUIRES = seccmd dbm
|
|||||||
# DIRS =
|
# DIRS =
|
||||||
|
|
||||||
CSRCS = vfyserv.c vfyutil.c
|
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
|
PROGRAM = vfyserv
|
||||||
|
|
||||||
|
@ -210,7 +210,7 @@ handle_connection(PRFileDesc *sslSocket, int connection)
|
|||||||
countRead += numBytes;
|
countRead += numBytes;
|
||||||
}
|
}
|
||||||
|
|
||||||
printSecurityInfo(sslSocket);
|
printSecurityInfo(stderr, sslSocket);
|
||||||
|
|
||||||
PR_Free(readBuffer);
|
PR_Free(readBuffer);
|
||||||
readBuffer = NULL;
|
readBuffer = NULL;
|
||||||
@ -224,6 +224,8 @@ handle_connection(PRFileDesc *sslSocket, int connection)
|
|||||||
return SECSuccess; /* success */
|
return SECSuccess; /* success */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define BYTE(n,i) (((i)>>((n)*8))&0xff)
|
||||||
|
|
||||||
/* one copy of this function is launched in a separate thread for each
|
/* one copy of this function is launched in a separate thread for each
|
||||||
** connection to be made.
|
** connection to be made.
|
||||||
*/
|
*/
|
||||||
@ -236,6 +238,7 @@ do_connects(void *a, int connection)
|
|||||||
char buffer[PR_NETDB_BUF_SIZE];
|
char buffer[PR_NETDB_BUF_SIZE];
|
||||||
PRStatus prStatus;
|
PRStatus prStatus;
|
||||||
PRIntn hostenum;
|
PRIntn hostenum;
|
||||||
|
PRInt32 ip;
|
||||||
SECStatus secStatus;
|
SECStatus secStatus;
|
||||||
|
|
||||||
/* Set up SSL secure socket. */
|
/* Set up SSL secure socket. */
|
||||||
@ -270,8 +273,11 @@ do_connects(void *a, int connection)
|
|||||||
return SECFailure;
|
return SECFailure;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* printf("Connecting to host %s (addr %d.%d.%d.%d) on port %d\n",
|
ip = PR_ntohl(addr->inet.ip);
|
||||||
host, hostEntry,port); */
|
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);
|
prStatus = PR_Connect(sslSocket, addr, PR_INTERVAL_NO_TIMEOUT);
|
||||||
if (prStatus != PR_SUCCESS) {
|
if (prStatus != PR_SUCCESS) {
|
||||||
@ -300,7 +306,8 @@ do_connects(void *a, int connection)
|
|||||||
|
|
||||||
secStatus = handle_connection(sslSocket, connection);
|
secStatus = handle_connection(sslSocket, connection);
|
||||||
if (secStatus != SECSuccess) {
|
if (secStatus != SECSuccess) {
|
||||||
errWarn("handle_connection");
|
/* error already printed out in handle_connection */
|
||||||
|
/* errWarn("handle_connection"); */
|
||||||
return secStatus;
|
return secStatus;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -356,6 +363,7 @@ client_main(unsigned short port,
|
|||||||
int
|
int
|
||||||
main(int argc, char **argv)
|
main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
|
char * certDir = NULL;
|
||||||
char * progName = NULL;
|
char * progName = NULL;
|
||||||
int connections = 1;
|
int connections = 1;
|
||||||
char * cipherString = NULL;
|
char * cipherString = NULL;
|
||||||
@ -374,7 +382,9 @@ main(int argc, char **argv)
|
|||||||
switch(optstate->option) {
|
switch(optstate->option) {
|
||||||
case 'C' : cipherString = PL_strdup(optstate->value); break;
|
case 'C' : cipherString = PL_strdup(optstate->value); break;
|
||||||
case 'c' : connections = PORT_Atoi(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 'p' : port = PORT_Atoi(optstate->value); break;
|
||||||
|
case 'w' : password = PL_strdup(optstate->value); break;
|
||||||
case '\0': hostName = PL_strdup(optstate->value); break;
|
case '\0': hostName = PL_strdup(optstate->value); break;
|
||||||
default : Usage(progName);
|
default : Usage(progName);
|
||||||
}
|
}
|
||||||
@ -391,20 +401,21 @@ main(int argc, char **argv)
|
|||||||
PK11_SetPasswordFunc(myPasswd);
|
PK11_SetPasswordFunc(myPasswd);
|
||||||
|
|
||||||
/* Initialize the NSS libraries. */
|
/* Initialize the NSS libraries. */
|
||||||
|
if (certDir) {
|
||||||
|
secStatus = NSS_Init(certDir);
|
||||||
|
} else {
|
||||||
secStatus = NSS_NoDB_Init(NULL);
|
secStatus = NSS_NoDB_Init(NULL);
|
||||||
if (secStatus != SECSuccess) {
|
|
||||||
exitErr("Client Error NSS_Init");
|
|
||||||
}
|
|
||||||
|
|
||||||
secStatus = SECMOD_AddNewModule("Builtins",
|
/* load the builtins */
|
||||||
|
SECMOD_AddNewModule("Builtins",
|
||||||
DLL_PREFIX"nssckbi."DLL_SUFFIX, 0, 0);
|
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();
|
NSS_SetDomesticPolicy();
|
||||||
SSL_CipherPrefSetDefault(SSL_RSA_WITH_NULL_MD5, PR_TRUE);
|
SSL_CipherPrefSetDefault(SSL_RSA_WITH_NULL_MD5, PR_TRUE);
|
||||||
|
|
||||||
|
@ -107,7 +107,11 @@ void errWarn(char *function);
|
|||||||
|
|
||||||
void exitErr(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. */
|
/* Some simple thread management routines. */
|
||||||
|
|
||||||
|
@ -32,7 +32,10 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "vfyserv.h"
|
#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. */
|
/* Declare SSL cipher suites. */
|
||||||
|
|
||||||
@ -127,6 +130,8 @@ myAuthCertificate(void *arg, PRFileDesc *socket,
|
|||||||
|
|
||||||
/* If this is a server, we're finished. */
|
/* If this is a server, we're finished. */
|
||||||
if (isServer || secStatus != SECSuccess) {
|
if (isServer || secStatus != SECSuccess) {
|
||||||
|
printCertProblems(stderr, (CERTCertDBHandle *)arg, cert,
|
||||||
|
checksig, certUsage, pinArg);
|
||||||
CERT_DestroyCertificate(cert);
|
CERT_DestroyCertificate(cert);
|
||||||
return secStatus;
|
return secStatus;
|
||||||
}
|
}
|
||||||
@ -204,7 +209,7 @@ myBadCertHandler(void *arg, PRFileDesc *socket)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
printf("Bad certificate: %d, %s\n", err, SSL_Strerror(err));
|
fprintf(stderr, "Bad certificate: %d, %s\n", err, SECU_Strerror(err));
|
||||||
|
|
||||||
return secStatus;
|
return secStatus;
|
||||||
}
|
}
|
||||||
@ -311,7 +316,7 @@ myGetClientAuthData(void *arg,
|
|||||||
SECStatus
|
SECStatus
|
||||||
myHandshakeCallback(PRFileDesc *socket, void *arg)
|
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;
|
return SECSuccess;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -334,7 +339,8 @@ disableAllSSLCiphers(void)
|
|||||||
PRUint16 suite = cipherSuites[i];
|
PRUint16 suite = cipherSuites[i];
|
||||||
rv = SSL_CipherPrefSetDefault(suite, PR_FALSE);
|
rv = SSL_CipherPrefSetDefault(suite, PR_FALSE);
|
||||||
if (rv != SECSuccess) {
|
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);
|
suite, i);
|
||||||
errWarn("SSL_CipherPrefSetDefault");
|
errWarn("SSL_CipherPrefSetDefault");
|
||||||
exit(2);
|
exit(2);
|
||||||
@ -352,9 +358,9 @@ void
|
|||||||
errWarn(char *function)
|
errWarn(char *function)
|
||||||
{
|
{
|
||||||
PRErrorCode errorNumber = PR_GetError();
|
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);
|
function, errorNumber, errorString);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -369,7 +375,7 @@ exitErr(char *function)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
printSecurityInfo(PRFileDesc *fd)
|
printSecurityInfo(FILE *outfile, PRFileDesc *fd)
|
||||||
{
|
{
|
||||||
char * cp; /* bulk cipher name */
|
char * cp; /* bulk cipher name */
|
||||||
char * ip; /* cert issuer DN */
|
char * ip; /* cert issuer DN */
|
||||||
@ -380,17 +386,23 @@ printSecurityInfo(PRFileDesc *fd)
|
|||||||
int result;
|
int result;
|
||||||
SSL3Statistics * ssl3stats = SSL_GetStatistics();
|
SSL3Statistics * ssl3stats = SSL_GetStatistics();
|
||||||
|
|
||||||
|
if (!outfile) {
|
||||||
|
outfile = stdout;
|
||||||
|
}
|
||||||
|
|
||||||
result = SSL_SecurityStatus(fd, &op, &cp, &kp0, &kp1, &ip, &sp);
|
result = SSL_SecurityStatus(fd, &op, &cp, &kp0, &kp1, &ip, &sp);
|
||||||
if (result != SECSuccess)
|
if (result != SECSuccess)
|
||||||
return;
|
return;
|
||||||
printf("bulk cipher %s, %d secret key bits, %d key bits, status: %d\n"
|
fprintf(outfile,
|
||||||
"subject DN: %s\n"
|
" bulk cipher %s, %d secret key bits, %d key bits, status: %d\n"
|
||||||
"issuer DN: %s\n", cp, kp1, kp0, op, sp, ip);
|
" subject DN:\n %s\n"
|
||||||
|
" issuer DN:\n %s\n", cp, kp1, kp0, op, sp, ip);
|
||||||
PR_Free(cp);
|
PR_Free(cp);
|
||||||
PR_Free(ip);
|
PR_Free(ip);
|
||||||
PR_Free(sp);
|
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_hits, ssl3stats->hch_sid_cache_misses,
|
||||||
ssl3stats->hch_sid_cache_not_ok);
|
ssl3stats->hch_sid_cache_not_ok);
|
||||||
|
|
||||||
@ -586,3 +598,103 @@ lockedVars_AddToCount(lockedVars * lv, int addend)
|
|||||||
PR_Unlock(lv->lock);
|
PR_Unlock(lv->lock);
|
||||||
return rv;
|
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 ;
|
||||||
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user