зеркало из https://github.com/mozilla/pjs.git
use error code in secutil.
Clean up the output. Print out cert chain parsing issues more completely.
This commit is contained in:
Родитель
dc57ad0730
Коммит
f9a5a2f1e7
|
@ -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 ;
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче