Hi all:
I am working on writing an xpcom component that checks which ciphers
work with a given target. So basically, I have a component which acts as a
SSL client and performs a handshake by setting a given cipher. I am
executing this in the context of the browser (and not as a independent
executable).
The cipherCheck works correctly, but I found that the NSS_Shutdown
function fails. Due to this, I guess the cleanup operation is not complete
and hence I am not able to run the cipherCheck again.
I have pasted the code snippet below. Please do let me know if anybody
has any ideas.
int checkCipher(const char *hostnameIP,int currPort, int currentCipher)
{
char *certdir=NULL;
const char *hostname;
PRNetAddr addr;
int ss_on;
char *ss_cipher;
int ss_keysize;
int ss_secretsize;
char *ss_issuer;
char *ss_subject;
int policy=1;
char *set_ssl_policy=NULL;
int print_ciphers=0;
char buf[10];
char netdbbuf[PR_NETDB_BUF_SIZE];
PRHostEnt hp;
PRStatus r;
PRNetAddr na;
SECStatus rv;
SECStatus whichCiphers;
int portnum=currPort;
PRFileDesc *s,*fd;
CERTCertDBHandle *handle;
CERTCertificate *c;
PRInt32 i;
int curr_error;
PRTime notbeforeT,notafterT;
hostname = hostnameIP;
if (!certdir) {
rv = NSS_NoDB_Init(NULL);
if (rv != SECSuccess)
{
OutputDebugString("NSS Init failed");
PRErrorCode retError = PR_GetError();
return retError;
}
SECMOD_AddNewModule("Builtins", "nssckbi.dll",0,0);
}
r = PR_GetHostByName(hostname,netdbbuf,PR_NETDB_BUF_SIZE,&hp);
if (r != PR_SUCCESS) {
OutputDebugString(" PR_GetHostByName failure");
return PR_GetError();
}
PR_EnumerateHostEnt(0,&hp,0,&na);
if (r != PR_SUCCESS) {
OutputDebugString("PR_EnumerateHostEnt failure");
return PR_GetError();
}
PR_InitializeNetAddr(PR_IpAddrNull,portnum,&na);
if (r != PR_SUCCESS) {
OutputDebugString("PR_InitializeNetAddr failure");
return PR_GetError();
}
fd = PR_NewTCPSocket();
if (fd == NULL) {
OutputDebugString("PR_NewTCPSocket failure");
return PR_GetError();
}
OutputDebugString("before ImportFD");
s = SSL_ImportFD(NULL,fd);
if (s == NULL) {
OutputDebugString("could not import fd into SSL");
return PR_GetError();
}
OutputDebugString("before SSL_OptionSet");
rv = SSL_OptionSet(s, SSL_SECURITY, PR_TRUE);
if (rv != SECSuccess)
{
OutputDebugString("SSL_OptionSet error for SSL_SECURITY");
return PR_GetError();
}
OutputDebugString("after SSL_OptionSet");
rv = SSL_OptionSet(s, SSL_HANDSHAKE_AS_CLIENT, PR_TRUE);
if (rv != SECSuccess) {
OutputDebugString("SSL_OptionSet error for SSL_HANDSHAKE_AS_CLIENT");
return PR_GetError();
}
whichCiphers = NSS_SetDomesticPolicy();
if (whichCiphers != SECSuccess)
{
OutputDebugString("NSS_SetDomesticPolicy error");
return PR_GetError();
}
SSL_ClearSessionCache();
if (policy) {
SetPolicy(s,currentCipher,policy);
}
rv = SSL_OptionSet(s, SSL_HANDSHAKE_AS_CLIENT, PR_TRUE);
if (rv != SECSuccess) {
OutputDebugString(" SSL_OptionSet error for SSL_HANDSHAKE_AS_CLIENT");
return PR_GetError();
}
if (SSL_AuthCertificateHook(s, MyAuthCertificateHook, (void *)handle) !=
SECSuccess)
{
OutputDebugString("auth cert hook() issues");
return PR_GetError();
}
if (SSL_BadCertHook(s,MyBadCertHandler,NULL) != SECSuccess)
{
OutputDebugString(" bad cert hook() issues");
return PR_GetError();
}
r = PR_Connect(s, &na, PR_TicksPerSecond()*100);
if (r != PR_SUCCESS) {
OutputDebugString("PR_Connect failure");
return PR_GetError();
}
rv = SSL_ForceHandshake(s);
if (rv != SECSuccess) {
OutputDebugString(" SSL Handshake failed");
PR_Close(s);
PRErrorCode retError = PR_GetError();
return retError;
}
rv = SSL_SecurityStatus(s, &ss_on, &ss_cipher,
&ss_keysize, &ss_secretsize,
&ss_issuer, &ss_subject);
c = SSL_PeerCertificate(s);
if (!c)
{
currRemainingTime = 0;
}
else
{
CERT_GetCertTimes(c,¬beforeT,¬afterT);
PRTime currTime = PR_Now();
currRemainingTime = currTime - notafterT;
}
PR_Close(s);
if (NSS_Shutdown() != SECSuccess)
{
return 1;
}
if (!isSSLv2Gl)
{
if (currentCipher >= startSSLv2 || currentCipher <= endSSLv2)
{
isSSLv2Gl=1;
}
}
return ss_secretsize;
}
Best Regards.
Umesh.
_______________________________________________
dev-tech-crypto mailing list
dev-tech-crypto@lists.mozilla.org
https://lists.mozilla.org/listinfo/dev-tech-crypto