mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-28 23:31:56 +00:00
363476(vfyserv needs OCSP option) and 363477(vfyserv needs option to save server certs to local files. sr=kengert, r=neil.williams
This commit is contained in:
parent
d492a46e5d
commit
911502366b
@ -68,6 +68,7 @@
|
||||
#include "prnetdb.h"
|
||||
#include "nss.h"
|
||||
#include "secutil.h"
|
||||
#include "ocsp.h"
|
||||
|
||||
#include "vfyserv.h"
|
||||
|
||||
@ -81,14 +82,48 @@ char *certNickname = NULL;
|
||||
char *hostName = NULL;
|
||||
char *password = NULL;
|
||||
unsigned short port = 0;
|
||||
PRBool dumpChain;
|
||||
|
||||
static void
|
||||
Usage(const char *progName)
|
||||
{
|
||||
fprintf(stderr,
|
||||
"Usage: %s [-p port] [-c connections] [-d dbdir] [-w password]\n"
|
||||
"\t\t[-C cipher(s)] hostname\n",
|
||||
progName);
|
||||
PRFileDesc *pr_stderr;
|
||||
|
||||
pr_stderr = PR_STDERR;
|
||||
|
||||
PR_fprintf(pr_stderr, "Usage:\n"
|
||||
" %s [-c ] [-o] [-p port] [-d dbdir] [-w password]\n"
|
||||
" \t\t[-C cipher(s)] [-l <url> -t <nickname> ] hostname",
|
||||
progName);
|
||||
PR_fprintf (pr_stderr, "\nWhere:\n");
|
||||
PR_fprintf (pr_stderr,
|
||||
" %-13s dump server cert chain into files\n",
|
||||
"-c");
|
||||
PR_fprintf (pr_stderr,
|
||||
" %-13s perform server cert OCSP check\n",
|
||||
"-o");
|
||||
PR_fprintf (pr_stderr,
|
||||
" %-13s server port to be used\n",
|
||||
"-p");
|
||||
PR_fprintf (pr_stderr,
|
||||
" %-13s use security databases in \"dbdir\"\n",
|
||||
"-d dbdir");
|
||||
PR_fprintf (pr_stderr,
|
||||
" %-13s key database password\n",
|
||||
"-w password");
|
||||
PR_fprintf (pr_stderr,
|
||||
" %-13s communication cipher list\n",
|
||||
"-C cipher(s)");
|
||||
PR_fprintf (pr_stderr,
|
||||
" %-13s OCSP responder location. This location is used to\n"
|
||||
" %-13s check status of a server certificate. If not \n"
|
||||
" %-13s specified, location will be taken from the AIA\n"
|
||||
" %-13s server certificate extension.\n",
|
||||
"-l url", "", "", "");
|
||||
PR_fprintf (pr_stderr,
|
||||
" %-13s OCSP Trusted Responder Cert nickname\n\n",
|
||||
"-t nickname");
|
||||
|
||||
exit(1);
|
||||
}
|
||||
|
||||
@ -388,9 +423,12 @@ main(int argc, char **argv)
|
||||
char * progName = NULL;
|
||||
int connections = 1;
|
||||
char * cipherString = NULL;
|
||||
char * respUrl = NULL;
|
||||
char * respCertName = NULL;
|
||||
SECStatus secStatus;
|
||||
PLOptState * optstate;
|
||||
PLOptStatus status;
|
||||
PRBool doOcspCheck = PR_FALSE;
|
||||
|
||||
/* Call the NSPR initialization routines */
|
||||
PR_Init( PR_SYSTEM_THREAD, PR_PRIORITY_NORMAL, 1);
|
||||
@ -398,14 +436,17 @@ main(int argc, char **argv)
|
||||
progName = PORT_Strdup(argv[0]);
|
||||
|
||||
hostName = NULL;
|
||||
optstate = PL_CreateOptState(argc, argv, "C:c:d:n:p:w:");
|
||||
optstate = PL_CreateOptState(argc, argv, "C:cd:l:n:p:ot:w:");
|
||||
while ((status = PL_GetNextOpt(optstate)) == PL_OPT_OK) {
|
||||
switch(optstate->option) {
|
||||
case 'C' : cipherString = PL_strdup(optstate->value); break;
|
||||
case 'c' : connections = PORT_Atoi(optstate->value); break;
|
||||
case 'c' : dumpChain = PR_TRUE; break;
|
||||
case 'd' : certDir = PL_strdup(optstate->value); break;
|
||||
case 'l' : respUrl = PL_strdup(optstate->value); break;
|
||||
case 'p' : port = PORT_Atoi(optstate->value); break;
|
||||
case 'w' : password = PL_strdup(optstate->value); break;
|
||||
case 'o' : doOcspCheck = PR_TRUE; break;
|
||||
case 't' : respCertName = PL_strdup(optstate->value); break;
|
||||
case 'w' : password = PL_strdup(optstate->value); break;
|
||||
case '\0': hostName = PL_strdup(optstate->value); break;
|
||||
default : Usage(progName);
|
||||
}
|
||||
@ -418,6 +459,14 @@ main(int argc, char **argv)
|
||||
if (port == 0 || hostName == NULL)
|
||||
Usage(progName);
|
||||
|
||||
if (doOcspCheck &&
|
||||
((respCertName != NULL && respUrl == NULL) ||
|
||||
(respUrl != NULL && respCertName == NULL))) {
|
||||
SECU_PrintError (progName, "options -l <url> and -t "
|
||||
"<responder> must be used together");
|
||||
Usage(progName);
|
||||
}
|
||||
|
||||
/* Set our password function callback. */
|
||||
PK11_SetPasswordFunc(myPasswd);
|
||||
|
||||
@ -436,6 +485,38 @@ main(int argc, char **argv)
|
||||
}
|
||||
SECU_RegisterDynamicOids();
|
||||
|
||||
if (doOcspCheck == PR_TRUE) {
|
||||
SECStatus rv;
|
||||
CERTCertDBHandle *handle = CERT_GetDefaultCertDB();
|
||||
if (handle == NULL) {
|
||||
SECU_PrintError (progName, "problem getting certdb handle");
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
rv = CERT_EnableOCSPChecking (handle);
|
||||
if (rv != SECSuccess) {
|
||||
SECU_PrintError (progName, "error enabling OCSP checking");
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if (respUrl != NULL) {
|
||||
rv = CERT_SetOCSPDefaultResponder (handle, respUrl,
|
||||
respCertName);
|
||||
if (rv != SECSuccess) {
|
||||
SECU_PrintError (progName,
|
||||
"error setting default responder");
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
rv = CERT_EnableOCSPDefaultResponder (handle);
|
||||
if (rv != SECSuccess) {
|
||||
SECU_PrintError (progName,
|
||||
"error enabling default responder");
|
||||
goto cleanup;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* All cipher suites except RSA_NULL_MD5 are enabled by
|
||||
* Domestic Policy. */
|
||||
NSS_SetDomesticPolicy();
|
||||
@ -485,6 +566,13 @@ main(int argc, char **argv)
|
||||
|
||||
client_main(port, connections, hostName);
|
||||
|
||||
cleanup:
|
||||
if (doOcspCheck) {
|
||||
CERTCertDBHandle *handle = CERT_GetDefaultCertDB();
|
||||
CERT_DisableOCSPDefaultResponder(handle);
|
||||
CERT_DisableOCSPChecking (handle);
|
||||
}
|
||||
|
||||
if (NSS_Shutdown() != SECSuccess) {
|
||||
exit(1);
|
||||
}
|
||||
|
@ -40,6 +40,10 @@
|
||||
#include "nspr.h"
|
||||
#include "secutil.h"
|
||||
|
||||
|
||||
extern PRBool dumpChain;
|
||||
extern void dumpCertChain(CERTCertificate *, SECCertUsage);
|
||||
|
||||
/* Declare SSL cipher suites. */
|
||||
|
||||
int ssl2CipherSuites[] = {
|
||||
@ -136,6 +140,10 @@ myAuthCertificate(void *arg, PRFileDesc *socket,
|
||||
cert = SSL_PeerCertificate(socket);
|
||||
|
||||
pinArg = SSL_RevealPinArg(socket);
|
||||
|
||||
if (dumpChain == PR_TRUE) {
|
||||
dumpCertChain(cert, certUsage);
|
||||
}
|
||||
|
||||
secStatus = CERT_VerifyCertificateNow((CERTCertDBHandle *)arg,
|
||||
cert,
|
||||
@ -616,3 +624,43 @@ lockedVars_AddToCount(lockedVars * lv, int addend)
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Dump cert chain in to cert.* files. This function is will
|
||||
* create collisions while dumping cert chains if called from
|
||||
* multiple treads. But it should not be a problem since we
|
||||
* consider vfyserv to be single threaded(see bug 353477).
|
||||
*/
|
||||
|
||||
void
|
||||
dumpCertChain(CERTCertificate *cert, SECCertUsage usage)
|
||||
{
|
||||
CERTCertificateList *certList;
|
||||
int count = 0;
|
||||
|
||||
certList = CERT_CertChainFromCert(cert, usage, PR_TRUE);
|
||||
if (certList == NULL) {
|
||||
errWarn("CERT_CertChainFromCert");
|
||||
return;
|
||||
}
|
||||
|
||||
for(count = 0; count < (unsigned int)certList->len; count++) {
|
||||
char certFileName[16];
|
||||
PRFileDesc *cfd;
|
||||
|
||||
PR_snprintf(certFileName, sizeof certFileName, "cert.%03d",
|
||||
count);
|
||||
cfd = PR_Open(certFileName, PR_WRONLY|PR_CREATE_FILE|PR_TRUNCATE,
|
||||
0664);
|
||||
if (!cfd) {
|
||||
PR_fprintf(PR_STDOUT,
|
||||
"Error: couldn't save cert der in file '%s'\n",
|
||||
certFileName);
|
||||
} else {
|
||||
PR_Write(cfd, certList->certs[count].data, certList->certs[count].len);
|
||||
PR_Close(cfd);
|
||||
PR_fprintf(PR_STDOUT, "Cert file %s was created.\n", certFileName);
|
||||
}
|
||||
}
|
||||
CERT_DestroyCertificateList(certList);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user