Author: jmagne
Update of /cvs/dirsec/esc/src/app/xpcom
In directory cvs1.fedora.phx.redhat.com:/tmp/cvs-serv27580/app/xpcom
Modified Files:
Makefile.sdk rhCoolKey.cpp rhCoolKey.h
Log Message:
Bugzilla#479722 ESC to TPS SSL communication problem with renewed TPS cert.
Index: Makefile.sdk
===================================================================
RCS file: /cvs/dirsec/esc/src/app/xpcom/Makefile.sdk,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -r1.3 -r1.4
--- Makefile.sdk 17 Apr 2009 00:11:11 -0000 1.3
+++ Makefile.sdk 19 Jun 2009 21:03:39 -0000 1.4
@@ -109,7 +109,7 @@
CPPFLAGS += -fno-rtti \
-fno-exceptions \
-fshort-wchar -fPIC
-GECKO_LD_LIBS=-L$(GECKO_SDK_PATH)/lib $(GECKO_SDK_PATH)/lib/libxpcomglue.a -lnss3
-lcrmf -lssl3 -lsmime3 -lplds4 -lplc4 -lnspr4 -lpthread -ldl
+GECKO_LD_LIBS=-L$(GECKO_SDK_PATH)/lib $(GECKO_SDK_PATH)/lib/libxpcomglue.a -lnssutil3
-lnss3 -lcrmf -lssl3 -lsmime3 -lplds4 -lplc4 -lnspr4 -lpthread -ldl
endif
ifeq ($(OS_ARCH),WINNT)
@@ -145,7 +145,7 @@
GECKO_INCLUDES += -I $(GECKO_SDK_PATH)/sdk/include
OBJECT = rhCoolKey.obj
OBJECTCSP = CoolKeyCSP.obj
-COOL_LDFLAGS = -IMPLIB:fake-import /LIBPATH:$(CORE_DIST)/lib ckymanager.lib
httpchunked.lib $(GECKO_LD_LIBS) nss3.lib ssl3.lib smime3.lib softokn3.lib
/LIBPATH:$(CKY_LIB_LDD) libckyapplet.lib crypt32.lib kernel32.lib user32.lib gdi32.lib
winmm.lib wsock32.lib advapi32.lib /NODEFAULTLIB:libc.lib
+COOL_LDFLAGS = -IMPLIB:fake-import /LIBPATH:$(CORE_DIST)/lib ckymanager.lib
httpchunked.lib $(GECKO_LD_LIBS) nssutil3.lib nss3.lib ssl3.lib smime3.lib softokn3.lib
/LIBPATH:$(CKY_LIB_LDD) libckyapplet.lib crypt32.lib kernel32.lib user32.lib gdi32.lib
winmm.lib wsock32.lib advapi32.lib /NODEFAULTLIB:libc.lib
endif
ifeq ($(OS_ARCH),Darwin)
Index: rhCoolKey.cpp
===================================================================
RCS file: /cvs/dirsec/esc/src/app/xpcom/rhCoolKey.cpp,v
retrieving revision 1.11
retrieving revision 1.12
diff -u -r1.11 -r1.12
--- rhCoolKey.cpp 13 Jun 2009 23:44:51 -0000 1.11
+++ rhCoolKey.cpp 19 Jun 2009 21:03:39 -0000 1.12
@@ -30,7 +30,7 @@
#else
#include "nsServiceManagerUtils.h"
#endif
-
+#include "pipnss/nsICertOverrideService.h"
#include "nsIPrefBranch.h"
#include "nsIPrefService.h"
#include "nsCOMPtr.h"
@@ -69,6 +69,7 @@
#endif
#define PSM_COMPONENT_CONTRACTID "(a)mozilla.org/psm;1"
+#define NS_CERTOVERRIDE_CONTRACTID "(a)mozilla.org/security/certoverride;1"
static const nsIID kIModuleIID = NS_IMODULE_IID;
static const nsIID kIFactoryIID = NS_IFACTORY_IID;
@@ -89,6 +90,7 @@
std::list< nsCOMPtr <rhIKeyNotify> > rhCoolKey::gNotifyListeners;
+PRLock* rhCoolKey::certCBLock=NULL;
PRBool rhCoolKey::gAutoEnrollBlankTokens = PR_FALSE;
@@ -190,6 +192,13 @@
mCSPListener = nsnull;
#endif
+ certCBLock = PR_NewLock();
+
+ if(!certCBLock) {
+ PR_LOG( coolKeyLog, PR_LOG_ERROR, ("%s Failed to create lock exiting!
\n",GetTStamp(tBuff,56)));
+ exit(1);
+ }
+
PRBool res = InitInstance();
if(res == PR_FALSE)
@@ -207,6 +216,10 @@
char tBuff[56];
PR_LOG( coolKeyLog, PR_LOG_DEBUG, ("%s rhCoolKey::~rhCoolKey: %p
\n",GetTStamp(tBuff,56),this));
+
+ if(certCBLock) {
+ PR_DestroyLock(certCBLock);
+ }
}
void rhCoolKey::ShutDownInstance()
@@ -255,6 +268,212 @@
return S_OK;
}
+struct BadCertData {
+ PRErrorCode error;
+ PRInt32 port;
+};
+
+typedef struct BadCertData BadCertData;
+
+SECStatus rhCoolKey::badCertHandler(void *arg, PRFileDesc *fd)
+{
+ SECStatus secStatus = SECFailure;
+ PRErrorCode err;
+ char *host = NULL;
+ PRInt32 port = 0;
+ CERTCertificate *serverCert = NULL;
+ PRUint32 errorBits = 0;
+ char tBuff[56];
+
+ PR_Lock(certCBLock);
+
+ if (!arg || !fd) {
+ PR_Unlock(certCBLock);
+ return secStatus;
+ }
+
+ // Retrieve callback data from NssHttpClient
+ // Caller cleans up this data
+ BadCertData *data = (BadCertData *) arg;
+ data->error = err = PORT_GetError();
+
+
+ /* If any of the cases in the switch are met, then we will proceed */
+
+ switch (err) {
+ case SEC_ERROR_INVALID_AVA:
+ case SEC_ERROR_INVALID_TIME:
+ case SEC_ERROR_BAD_SIGNATURE:
+ case SEC_ERROR_EXPIRED_CERTIFICATE:
+ case SEC_ERROR_UNKNOWN_ISSUER:
+ case SEC_ERROR_UNTRUSTED_CERT:
+ case SEC_ERROR_CERT_VALID:
+ case SEC_ERROR_EXPIRED_ISSUER_CERTIFICATE:
+ case SEC_ERROR_CRL_EXPIRED:
+ case SEC_ERROR_CRL_BAD_SIGNATURE:
+ case SEC_ERROR_EXTENSION_VALUE_INVALID:
+ case SEC_ERROR_CA_CERT_INVALID:
+ case SEC_ERROR_CERT_USAGES_INVALID:
+ case SEC_ERROR_UNKNOWN_CRITICAL_EXTENSION:
+ case SEC_ERROR_EXTENSION_NOT_FOUND: // Added by Rob 5/21/2002
+ secStatus = SECSuccess;
+ break;
+ default:
+ secStatus = SECFailure;
+ break;
+ }
+
+ if(secStatus == SECSuccess) {
+ PR_Unlock(certCBLock);
+ return secStatus;
+ }
+
+ // Collect errors to compare with override service output
+ switch(err) {
+ case SEC_ERROR_UNTRUSTED_ISSUER:
+ errorBits |= nsICertOverrideService::ERROR_UNTRUSTED;
+ break;
+ case SSL_ERROR_BAD_CERT_DOMAIN:
+ errorBits |= nsICertOverrideService::ERROR_MISMATCH;
+ break;
+ case SEC_ERROR_EXPIRED_CERTIFICATE:
+ errorBits |= nsICertOverrideService::ERROR_TIME;
+ default:
+ break;
+ };
+
+ // Now proceed to see if we have an exception.
+ // Get the server certificate that was rejected.
+ serverCert = SSL_PeerCertificate(fd);
+
+ if(!serverCert) {
+ PR_Unlock(certCBLock);
+ return secStatus;
+ }
+
+ port = data->port;
+ host = SSL_RevealURL(fd);
+
+ if(!host || port <= 0) {
+ PR_Unlock(certCBLock);
+ return secStatus;
+ }
+
+ PR_LOG(coolKeyLog, PR_LOG_DEBUG,
+ ("%s rhCoolKey::badCertHandler enter: error: %d url: %s
port: %d \n",
+ GetTStamp(tBuff,56),err,host,port)
+ );
+
+ PRBool isTemporaryOverride = PR_FALSE;
+ PRUint32 overrideBits = 0;
+ PRBool overrideResult = PR_FALSE;
+
+ // Use the nsICertOverrideService to see if we have
+ // previously trusted this certificate.
+ nsCOMPtr<nsICertOverrideService> overrideService =
+ do_GetService(NS_CERTOVERRIDE_CONTRACTID);
+
+ const nsEmbedCString nsHost(host);
+ nsEmbedCString hashAlg,fingerPrint;
+
+ nsresult nsrv;
+ unsigned char* fingerprint=NULL;
+ if(overrideService) {
+ nsrv = overrideService->GetValidityOverride((const nsACString &)nsHost,
+ port,(nsACString &)hashAlg,
+ (nsACString&)fingerPrint,&overrideBits,
+ &isTemporaryOverride,&overrideResult
+ );
+ if(nsrv == NS_OK) {
+ PR_LOG(coolKeyLog, PR_LOG_DEBUG,
+ ("%s rhCoolKey::badCertHandler res %d print %s len %d bits %u temp %d
alg: %s \n",
+ GetTStamp(tBuff,56),overrideResult,fingerPrint.get(),
+ fingerPrint.Length(),overrideBits, isTemporaryOverride,hashAlg.get())
+ );
+ }
+
+ PRBool certMatches = PR_FALSE;
+
+ if( (nsrv == NS_OK) && overrideResult) {
+ SECItem oid;
+ oid.data = nsnull;
+ oid.len = 0;
+ SECStatus srv = SEC_StringToOID(nsnull, &oid,
+ hashAlg.get(), hashAlg.Length());
+
+ if (srv != SECSuccess) {
+ PR_Free(host);
+ host=NULL;
+ CERT_DestroyCertificate(serverCert);
+ serverCert=NULL;
+ PR_Unlock(certCBLock);
+ return secStatus;
+ }
+
+ SECOidTag oid_tag = SECOID_FindOIDTag(&oid);
+
+ unsigned int hash_len = HASH_ResultLenByOidTag(oid_tag);
+ fingerprint = new unsigned char[hash_len];
+
+ if(!fingerprint) {
+ CERT_DestroyCertificate(serverCert);
+ serverCert=NULL;
+ PR_Unlock(certCBLock);
+ return secStatus;
+ }
+
+ SECItem computedPrint;
+ memset(fingerprint, 0, sizeof fingerprint);
+ PK11_HashBuf(oid_tag, fingerprint,
+ serverCert->derCert.data, serverCert->derCert.len);
+ CERT_DestroyCertificate(serverCert);
+ serverCert=NULL;
+
+ computedPrint.data=fingerprint;
+ computedPrint.len=hash_len;
+
+ char *formattedPrint = CERT_Hexify(&computedPrint,1);
+ char *inputPrint = (char *)fingerPrint.get();
+
+ //Compare fingerprints.
+
+ if(formattedPrint && inputPrint) {
+ if(!PL_strcmp(formattedPrint, inputPrint))
+ certMatches = PR_TRUE;
+ }
+ PR_LOG( coolKeyLog, PR_LOG_DEBUG, ("%s certMatches: %d \n",
+ GetTStamp(tBuff,56),certMatches)
+ );
+
+ if(formattedPrint) {
+ PORT_Free(formattedPrint);
+ formattedPrint = NULL;
+ }
+ } else {
+ PR_LOG( coolKeyLog, PR_LOG_DEBUG, ("%s override test failed. \n",
+ GetTStamp(tBuff,56))
+ );
+ }
+
+ if( certMatches ) {
+ if(overrideBits | errorBits)
+ secStatus = SECSuccess;
+ }
+ }
+
+ PR_Free(host);
+ host = NULL;
+ if(fingerprint) {
+ delete [] fingerprint;
+ fingerprint = NULL;
+ }
+
+ PR_Unlock(certCBLock);
+
+ return secStatus;
+}
+
+
HRESULT rhCoolKey::doSetCoolKeyConfigValue(const char *aName, const char *aValue)
{
@@ -340,7 +559,7 @@
nssComponent
= do_GetService(PSM_COMPONENT_CONTRACTID);
- CoolKeySetCallbacks(Dispatch,Reference, Release,doGetCoolKeyConfigValue
,doSetCoolKeyConfigValue);
+ CoolKeySetCallbacks(Dispatch,Reference, Release,doGetCoolKeyConfigValue
,doSetCoolKeyConfigValue,badCertHandler);
mProxy = CreateProxyObject();
Index: rhCoolKey.h
===================================================================
RCS file: /cvs/dirsec/esc/src/app/xpcom/rhCoolKey.h,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -u -r1.1.1.1 -r1.2
--- rhCoolKey.h 12 Jun 2006 23:39:50 -0000 1.1.1.1
+++ rhCoolKey.h 19 Jun 2009 21:03:39 -0000 1.2
@@ -22,6 +22,15 @@
#include "nsIGenericFactory.h"
#include "nsEmbedString.h"
#include <list>
+#include "nspr.h"
+#include "prio.h"
+#include "ssl.h"
+#include "pk11func.h"
+#include "cert.h"
+#include "sslerr.h"
+#include "secerr.h"
+#include "sechash.h"
+
#include "CoolKey.h"
#include "nsCOMPtr.h"
#include "nsIObserver.h"
@@ -92,6 +101,7 @@
static HRESULT doSetCoolKeyConfigValue(const char *aName, const char *aValue);
static const char *doGetCoolKeyConfigValue(const char *aName );
+ static SECStatus badCertHandler(void *arg, PRFileDesc *fd);
protected:
/* additional members */
@@ -107,6 +117,8 @@
static std::list< nsCOMPtr <rhIKeyNotify> > gNotifyListeners;
+ static PRLock* certCBLock;
+
rhICoolKey* mProxy;
static PRBool gAutoEnrollBlankTokens;