зеркало из https://github.com/mozilla/gecko-dev.git
SmartCard support checkin.
Bug 284366 "PSM needs to handle Smart Cards seamlessly" r=timeless sr=jst a=shaver
This commit is contained in:
Родитель
a1da7c82a3
Коммит
3bf4387d1c
|
@ -38,10 +38,11 @@
|
|||
|
||||
#include "domstubs.idl"
|
||||
|
||||
[scriptable, uuid(33276f5d-3499-4ab9-acea-d85a9fceeccd)]
|
||||
[scriptable, uuid(d2b675a5-f05b-4172-bac2-24cc39ffd398)]
|
||||
interface nsIDOMCrypto : nsISupports
|
||||
{
|
||||
readonly attribute DOMString version;
|
||||
attribute boolean enableSmartCardEvents;
|
||||
|
||||
nsIDOMCRMFObject generateCRMFRequest(/* ... */);
|
||||
DOMString importUserCertificates(in DOMString nickname,
|
||||
|
|
|
@ -67,6 +67,7 @@ XPIDLSRCS = \
|
|||
nsIDOMPopupBlockedEvent.idl \
|
||||
nsIDOMBeforeUnloadEvent.idl \
|
||||
nsIDOMNSEventTarget.idl \
|
||||
nsIDOMSmartCardEvent.idl \
|
||||
$(NULL)
|
||||
|
||||
include $(topsrcdir)/config/rules.mk
|
||||
|
|
|
@ -332,6 +332,9 @@ enum nsDOMClassInfoID {
|
|||
eDOMClassInfo_CanvasPattern_id,
|
||||
#endif
|
||||
|
||||
// SmartCard Events
|
||||
eDOMClassInfo_SmartCardEvent_id,
|
||||
|
||||
// This one better be the last one in this list
|
||||
eDOMClassInfoIDCount
|
||||
};
|
||||
|
|
|
@ -207,6 +207,7 @@
|
|||
#include "nsIDOMPopupBlockedEvent.h"
|
||||
#include "nsIDOMBeforeUnloadEvent.h"
|
||||
#include "nsIDOMMutationEvent.h"
|
||||
#include "nsIDOMSmartCardEvent.h"
|
||||
#include "nsIDOMNSDocumentStyle.h"
|
||||
#include "nsIDOMDocumentRange.h"
|
||||
#include "nsIDOMDocumentTraversal.h"
|
||||
|
@ -1001,6 +1002,9 @@ static nsDOMClassInfoData sClassInfoData[] = {
|
|||
NS_DEFINE_CLASSINFO_DATA(CanvasPattern, nsDOMGenericSH,
|
||||
DOM_DEFAULT_SCRIPTABLE_FLAGS)
|
||||
#endif // MOZ_ENABLE_CANVAS
|
||||
|
||||
NS_DEFINE_CLASSINFO_DATA(SmartCardEvent, nsDOMGenericSH,
|
||||
DOM_DEFAULT_SCRIPTABLE_FLAGS)
|
||||
};
|
||||
|
||||
nsIXPConnect *nsDOMClassInfo::sXPConnect = nsnull;
|
||||
|
@ -1728,6 +1732,10 @@ nsDOMClassInfo::Init()
|
|||
DOM_CLASSINFO_EVENT_MAP_ENTRIES
|
||||
DOM_CLASSINFO_MAP_END
|
||||
|
||||
DOM_CLASSINFO_MAP_BEGIN(SmartCardEvent, nsIDOMSmartCardEvent)
|
||||
DOM_CLASSINFO_MAP_ENTRY(nsIDOMSmartCardEvent)
|
||||
DOM_CLASSINFO_MAP_END
|
||||
|
||||
DOM_CLASSINFO_MAP_BEGIN(MutationEvent, nsIDOMMutationEvent)
|
||||
DOM_CLASSINFO_MAP_ENTRY(nsIDOMMutationEvent)
|
||||
DOM_CLASSINFO_EVENT_MAP_ENTRIES
|
||||
|
|
|
@ -495,6 +495,11 @@ nsGlobalWindow::SetNewDocument(nsIDOMDocument* aDocument,
|
|||
|
||||
// Let go of the cached principal since we no longer need it.
|
||||
mDocumentPrincipal = nsnull;
|
||||
|
||||
// clear smartcard events, our document has gone away.
|
||||
if (mCrypto) {
|
||||
mCrypto->SetEnableSmartCardEvents(PR_FALSE);
|
||||
}
|
||||
}
|
||||
|
||||
if (mFirstDocumentLoad) {
|
||||
|
|
|
@ -87,6 +87,9 @@ CPPSRCS = \
|
|||
nsCRLManager.cpp \
|
||||
nsNSSShutDown.cpp \
|
||||
nsNTLMAuthModule.cpp \
|
||||
nsNSSEvent.cpp \
|
||||
nsSmartCardMonitor.cpp \
|
||||
nsSmartCardEvent.cpp \
|
||||
$(NULL)
|
||||
|
||||
ifdef MOZ_XUL
|
||||
|
|
|
@ -58,8 +58,6 @@
|
|||
#include "nsIScriptContext.h"
|
||||
#include "nsIScriptGlobalObject.h"
|
||||
#include "nsIXPConnect.h"
|
||||
#include "nsIEventQueueService.h"
|
||||
#include "nsIEventQueue.h"
|
||||
#include "nsIRunnable.h"
|
||||
#include "nsIWindowWatcher.h"
|
||||
#include "nsIPrompt.h"
|
||||
|
@ -143,17 +141,6 @@ typedef struct nsKeyPairInfoStr {
|
|||
nsKeyGenType keyGenType; /* What type of key gen are we doing.*/
|
||||
} nsKeyPairInfo;
|
||||
|
||||
//
|
||||
// This is the class we'll use to run the keygen done code
|
||||
// as an nsIRunnable object;
|
||||
//
|
||||
struct CryptoRunnableEvent : PLEvent {
|
||||
CryptoRunnableEvent(nsIRunnable* runnable);
|
||||
~CryptoRunnableEvent();
|
||||
|
||||
nsIRunnable* mRunnable;
|
||||
};
|
||||
|
||||
|
||||
//This class is just used to pass arguments
|
||||
//to the nsCryptoRunnable event.
|
||||
|
@ -231,34 +218,19 @@ NS_INTERFACE_MAP_END
|
|||
NS_IMPL_ADDREF(nsPkcs11)
|
||||
NS_IMPL_RELEASE(nsPkcs11)
|
||||
|
||||
// QueryInterface implementation for nsCryptoRunnable
|
||||
NS_INTERFACE_MAP_BEGIN(nsCryptoRunnable)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIRunnable)
|
||||
NS_INTERFACE_MAP_ENTRY(nsISupports)
|
||||
NS_INTERFACE_MAP_END
|
||||
// ISupports implementation for nsCryptoRunnable
|
||||
NS_IMPL_ISUPPORTS1(nsCryptoRunnable, nsIRunnable);
|
||||
|
||||
NS_IMPL_ADDREF(nsCryptoRunnable)
|
||||
NS_IMPL_RELEASE(nsCryptoRunnable)
|
||||
// ISupports implementation for nsP12Runnable
|
||||
NS_IMPL_ISUPPORTS1(nsP12Runnable, nsIRunnable);
|
||||
|
||||
// QueryInterface implementation for nsP12Runnable
|
||||
NS_INTERFACE_MAP_BEGIN(nsP12Runnable)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIRunnable)
|
||||
NS_INTERFACE_MAP_ENTRY(nsISupports)
|
||||
NS_INTERFACE_MAP_END_THREADSAFE
|
||||
|
||||
NS_IMPL_THREADSAFE_ADDREF(nsP12Runnable)
|
||||
NS_IMPL_THREADSAFE_RELEASE(nsP12Runnable)
|
||||
|
||||
NS_INTERFACE_MAP_BEGIN(nsCryptoRunArgs)
|
||||
NS_INTERFACE_MAP_ENTRY(nsISupports)
|
||||
NS_INTERFACE_MAP_END_THREADSAFE
|
||||
|
||||
NS_IMPL_THREADSAFE_ADDREF(nsCryptoRunArgs)
|
||||
NS_IMPL_THREADSAFE_RELEASE(nsCryptoRunArgs)
|
||||
// ISupports implementation for nsCryptoRunArgs
|
||||
NS_IMPL_ISUPPORTS0(nsCryptoRunArgs);
|
||||
|
||||
static NS_DEFINE_CID(kNSSComponentCID, NS_NSSCOMPONENT_CID);
|
||||
|
||||
nsCrypto::nsCrypto()
|
||||
nsCrypto::nsCrypto() :
|
||||
mEnableSmartCardEvents(PR_FALSE)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -266,22 +238,31 @@ nsCrypto::~nsCrypto()
|
|||
{
|
||||
}
|
||||
|
||||
//Grab the UI event queue so that we can post some events to it.
|
||||
nsIEventQueue*
|
||||
nsCrypto::GetUIEventQueue()
|
||||
NS_IMETHODIMP
|
||||
nsCrypto::SetEnableSmartCardEvents(PRBool aEnable)
|
||||
{
|
||||
nsresult rv;
|
||||
nsCOMPtr<nsIEventQueueService> service =
|
||||
do_GetService(NS_EVENTQUEUESERVICE_CONTRACTID, &rv);
|
||||
if (NS_FAILED(rv))
|
||||
return nsnull;
|
||||
|
||||
nsIEventQueue* result = nsnull;
|
||||
rv = service->GetThreadEventQueue(NS_UI_THREAD, &result);
|
||||
if (NS_FAILED(rv))
|
||||
return nsnull;
|
||||
|
||||
return result;
|
||||
|
||||
// this has the side effect of starting the nssComponent (and initializing
|
||||
// NSS) even if it isn't already going. Starting the nssComponent is a
|
||||
// prerequisite for getting smartCard events.
|
||||
if (aEnable) {
|
||||
nsCOMPtr<nsINSSComponent> nssComponent(do_GetService(kNSSComponentCID, &rv));
|
||||
}
|
||||
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
mEnableSmartCardEvents = aEnable;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsCrypto::GetEnableSmartCardEvents(PRBool *aEnable)
|
||||
{
|
||||
*aEnable = mEnableSmartCardEvents;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
//These next few functions are based on implementation in
|
||||
|
@ -1424,6 +1405,7 @@ loser:
|
|||
nsFreeCertReqMessages(certReqMsgs,numRequests);
|
||||
return nsnull;;
|
||||
}
|
||||
|
||||
|
||||
//The top level method which is a member of nsIDOMCrypto
|
||||
//for generate a base64 encoded CRMF request.
|
||||
|
@ -1639,41 +1621,11 @@ nsCrypto::GenerateCRMFRequest(nsIDOMCRMFObject** aReturn)
|
|||
if (!cryptoRunnable)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
CryptoRunnableEvent *runnable = new CryptoRunnableEvent(cryptoRunnable);
|
||||
if (!runnable) {
|
||||
nsresult rv = nsNSSEventPostToUIEventQueue(cryptoRunnable);
|
||||
if (NS_FAILED(rv))
|
||||
delete cryptoRunnable;
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
nsCOMPtr<nsIEventQueue>uiQueue = dont_AddRef(GetUIEventQueue());
|
||||
uiQueue->PostEvent(runnable);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
//A wrapper for PLEvent that we can use to post
|
||||
//our nsIRunnable Events.
|
||||
static void PR_CALLBACK
|
||||
handleCryptoRunnableEvent(CryptoRunnableEvent* aEvent)
|
||||
{
|
||||
aEvent->mRunnable->Run();
|
||||
}
|
||||
|
||||
static void PR_CALLBACK
|
||||
destroyCryptoRunnableEvent(CryptoRunnableEvent* aEvent)
|
||||
{
|
||||
delete aEvent;
|
||||
}
|
||||
|
||||
CryptoRunnableEvent::CryptoRunnableEvent(nsIRunnable* runnable)
|
||||
: mRunnable(runnable)
|
||||
{
|
||||
NS_ADDREF(mRunnable);
|
||||
PL_InitEvent(this, nsnull, PLHandleEventProc(handleCryptoRunnableEvent),
|
||||
PLDestroyEventProc(&destroyCryptoRunnableEvent));
|
||||
}
|
||||
|
||||
CryptoRunnableEvent::~CryptoRunnableEvent()
|
||||
{
|
||||
NS_RELEASE(mRunnable);
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
||||
|
@ -2043,7 +1995,6 @@ nsCrypto::ImportUserCertificates(const nsAString& aNickname,
|
|||
// later.
|
||||
nsCOMPtr<nsIRunnable> p12Runnable = new nsP12Runnable(certArr, numResponses,
|
||||
token);
|
||||
CryptoRunnableEvent *runnable;
|
||||
if (!p12Runnable) {
|
||||
rv = NS_ERROR_FAILURE;
|
||||
goto loser;
|
||||
|
@ -2054,13 +2005,9 @@ nsCrypto::ImportUserCertificates(const nsAString& aNickname,
|
|||
// memory on the way out.
|
||||
certArr = nsnull;
|
||||
|
||||
runnable = new CryptoRunnableEvent(p12Runnable);
|
||||
if (!runnable) {
|
||||
rv = NS_ERROR_FAILURE;
|
||||
rv = nsNSSEventPostToUIEventQueue(p12Runnable);
|
||||
if (NS_FAILED(rv))
|
||||
goto loser;
|
||||
}
|
||||
nsCOMPtr<nsIEventQueue>uiQueue = dont_AddRef(GetUIEventQueue());
|
||||
uiQueue->PostEvent(runnable);
|
||||
}
|
||||
|
||||
loser:
|
||||
|
@ -2623,6 +2570,11 @@ nsPkcs11::Deletemodule(const nsAString& aModuleName, PRInt32* aReturn)
|
|||
PRInt32 modType;
|
||||
SECStatus srv = SECMOD_DeleteModule(modName, &modType);
|
||||
if (srv == SECSuccess) {
|
||||
SECMODModule *module = SECMOD_FindModule(modName);
|
||||
if (module) {
|
||||
nssComponent->ShutdownSmartCardThread(module);
|
||||
SECMOD_DestroyModule(module);
|
||||
}
|
||||
if (modType == SECMOD_EXTERNAL) {
|
||||
nssComponent->GetPIPNSSBundleString("DelModuleExtSuccess", errorMessage);
|
||||
*aReturn = JS_OK_DEL_EXTERNAL_MOD;
|
||||
|
@ -2692,6 +2644,14 @@ nsPkcs11::Addmodule(const nsAString& aModuleName,
|
|||
PRUint32 cipherFlags = SECMOD_PubCipherFlagstoInternal(aCipherFlags);
|
||||
SECStatus srv = SECMOD_AddNewModule(moduleName, fullPath,
|
||||
mechFlags, cipherFlags);
|
||||
if (srv == SECSuccess) {
|
||||
SECMODModule *module = SECMOD_FindModule(moduleName);
|
||||
if (module) {
|
||||
nssComponent->LaunchSmartCardThread(module);
|
||||
SECMOD_DestroyModule(module);
|
||||
}
|
||||
}
|
||||
|
||||
nsMemory::Free(moduleName);
|
||||
nsMemory::Free(fullPath);
|
||||
|
||||
|
|
|
@ -42,9 +42,12 @@
|
|||
#include "nsIDOMCRMFObject.h"
|
||||
#include "nsIDOMCrypto.h"
|
||||
#include "nsIDOMPkcs11.h"
|
||||
#include "nsIRunnable.h"
|
||||
#include "nsString.h"
|
||||
#include "nsNSSEvent.h"
|
||||
#include "jsapi.h"
|
||||
#include "nsIPrincipal.h"
|
||||
#include "plevent.h"
|
||||
|
||||
#define NS_CRYPTO_CLASSNAME "Crypto JavaScript Class"
|
||||
#define NS_CRYPTO_CID \
|
||||
|
@ -58,7 +61,6 @@
|
|||
|
||||
class nsIPSMComponent;
|
||||
class nsIDOMScriptObjectFactory;
|
||||
class nsIEventQueue;
|
||||
|
||||
|
||||
class nsCRMFObject : public nsIDOMCRMFObject
|
||||
|
@ -89,8 +91,10 @@ public:
|
|||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSIDOMCRYPTO
|
||||
|
||||
private:
|
||||
static nsIPrincipal* GetScriptPrincipal(JSContext *cx);
|
||||
static nsIEventQueue* GetUIEventQueue();
|
||||
|
||||
PRBool mEnableSmartCardEvents;
|
||||
};
|
||||
|
||||
class nsPkcs11 : public nsIDOMPkcs11
|
||||
|
@ -104,6 +108,17 @@ public:
|
|||
|
||||
};
|
||||
|
||||
//
|
||||
// This is the class we'll use to post ui events
|
||||
//
|
||||
struct CryptoRunnableEvent : PLEvent {
|
||||
CryptoRunnableEvent(nsIRunnable* runnable);
|
||||
~CryptoRunnableEvent();
|
||||
|
||||
nsIRunnable* mRunnable;
|
||||
};
|
||||
|
||||
|
||||
#endif //_nsCrypto_h_
|
||||
|
||||
|
||||
|
|
|
@ -44,6 +44,7 @@
|
|||
#include "nsNSSComponent.h"
|
||||
#include "nsNSSCallbacks.h"
|
||||
#include "nsNSSIOLayer.h"
|
||||
#include "nsNSSEvent.h"
|
||||
|
||||
#include "nsNetUtil.h"
|
||||
#include "nsAppDirectoryServiceDefs.h"
|
||||
|
@ -51,6 +52,7 @@
|
|||
#include "nsIStreamListener.h"
|
||||
#include "nsIStringBundle.h"
|
||||
#include "nsIDirectoryService.h"
|
||||
#include "nsIDOMNode.h"
|
||||
#include "nsCURILoader.h"
|
||||
#include "nsDirectoryServiceDefs.h"
|
||||
#include "nsIProxyObjectManager.h"
|
||||
|
@ -59,6 +61,7 @@
|
|||
#include "nsIProfileChangeStatus.h"
|
||||
#include "nsNSSCertificate.h"
|
||||
#include "nsNSSHelper.h"
|
||||
#include "nsSmartCardMonitor.h"
|
||||
#include "prlog.h"
|
||||
#include "nsIPrefService.h"
|
||||
#include "nsIPrefBranch.h"
|
||||
|
@ -66,8 +69,15 @@
|
|||
#include "nsIDateTimeFormat.h"
|
||||
#include "nsDateTimeFormatCID.h"
|
||||
#include "nsAutoLock.h"
|
||||
#include "nsIEventQueueService.h"
|
||||
#include "nsIEventQueue.h"
|
||||
#include "nsIDOMEvent.h"
|
||||
#include "nsIDOMDocument.h"
|
||||
#include "nsIDOMDocumentEvent.h"
|
||||
#include "nsIDOMWindow.h"
|
||||
#include "nsIDOMWindowCollection.h"
|
||||
#include "nsIDOMWindowInternal.h"
|
||||
#include "nsIDOMSmartCardEvent.h"
|
||||
#include "nsIDOMCrypto.h"
|
||||
#include "nsIRunnable.h"
|
||||
#include "plevent.h"
|
||||
#include "nsCRT.h"
|
||||
|
@ -89,6 +99,7 @@
|
|||
#include "nsITokenPasswordDialogs.h"
|
||||
#include "nsICRLManager.h"
|
||||
#include "nsNSSShutDown.h"
|
||||
#include "nsSmartCardEvent.h"
|
||||
#include "nsICryptoHash.h"
|
||||
|
||||
#include "nss.h"
|
||||
|
@ -205,9 +216,10 @@ struct CRLDownloadEvent : PLEvent {
|
|||
nsCAutoString *urlString;
|
||||
nsIStreamListener *psmDownloader;
|
||||
};
|
||||
//Note that nsNSSComponent is a singleton object across all threads, and automatic downloads
|
||||
//are always scheduled sequentially - that is, once one crl download is complete, the next one
|
||||
//is scheduled
|
||||
|
||||
// Note that nsNSSComponent is a singleton object across all threads,
|
||||
// and automatic downloads are always scheduled sequentially - that is,
|
||||
// once one crl download is complete, the next one is scheduled
|
||||
static void PR_CALLBACK HandleCRLImportPLEvent(CRLDownloadEvent *aEvent)
|
||||
{
|
||||
nsresult rv;
|
||||
|
@ -228,8 +240,43 @@ static void PR_CALLBACK DestroyCRLImportPLEvent(CRLDownloadEvent* aEvent)
|
|||
delete aEvent;
|
||||
}
|
||||
|
||||
//This class is used to run the callback code
|
||||
//passed to the event handlers for smart card notification
|
||||
class nsTokenEventRunnable : public nsIRunnable {
|
||||
public:
|
||||
nsTokenEventRunnable(const nsAString &aType, const nsAString &aTokenName);
|
||||
virtual ~nsTokenEventRunnable();
|
||||
|
||||
NS_IMETHOD Run ();
|
||||
NS_DECL_ISUPPORTS
|
||||
private:
|
||||
nsString mType;
|
||||
nsString mTokenName;
|
||||
};
|
||||
|
||||
// ISuuports implementation for nsTokenEventRunnable
|
||||
NS_IMPL_THREADSAFE_ISUPPORTS1(nsTokenEventRunnable, nsIRunnable);
|
||||
|
||||
nsTokenEventRunnable::nsTokenEventRunnable(const nsAString &aType,
|
||||
const nsAString &aTokenName): mType(aType), mTokenName(aTokenName) { }
|
||||
|
||||
nsTokenEventRunnable::~nsTokenEventRunnable() { }
|
||||
|
||||
//Implementation that runs the callback passed to
|
||||
//crypto.generateCRMFRequest as an event.
|
||||
NS_IMETHODIMP
|
||||
nsTokenEventRunnable::Run()
|
||||
{
|
||||
nsresult rv;
|
||||
nsCOMPtr<nsINSSComponent> nssComponent(do_GetService(kNSSComponentCID, &rv));
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
return nssComponent->DispatchEvent(mType, mTokenName);
|
||||
}
|
||||
|
||||
nsNSSComponent::nsNSSComponent()
|
||||
:mNSSInitialized(PR_FALSE)
|
||||
:mNSSInitialized(PR_FALSE), mThreadList(nsnull)
|
||||
{
|
||||
mutex = PR_NewLock();
|
||||
|
||||
|
@ -287,6 +334,160 @@ nsNSSComponent::~nsNSSComponent()
|
|||
PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("nsNSSComponent::dtor finished\n"));
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsNSSComponent::PostEvent(const nsAString &eventType,
|
||||
const nsAString &tokenName)
|
||||
{
|
||||
nsresult rv;
|
||||
nsTokenEventRunnable *runnable =
|
||||
new nsTokenEventRunnable(eventType, tokenName);
|
||||
if (!runnable) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
rv = nsNSSEventPostToUIEventQueue(runnable);
|
||||
if (NS_FAILED(rv))
|
||||
delete runnable;
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsNSSComponent::DispatchEvent(const nsAString &eventType,
|
||||
const nsAString &tokenName)
|
||||
{
|
||||
// 'Dispatch' the event to all the windows. 'DispatchEventToWindow()' will
|
||||
// first check to see if a given window has requested crypto events.
|
||||
nsresult rv;
|
||||
nsCOMPtr<nsIWindowWatcher> windowWatcher =
|
||||
do_GetService(NS_WINDOWWATCHER_CONTRACTID, &rv);
|
||||
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsISimpleEnumerator> enumerator;
|
||||
rv = windowWatcher->GetWindowEnumerator(getter_AddRefs(enumerator));
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
PRBool hasMoreWindows;
|
||||
|
||||
while (NS_SUCCEEDED(enumerator->HasMoreElements(&hasMoreWindows))
|
||||
&& hasMoreWindows) {
|
||||
nsCOMPtr<nsISupports> supports;
|
||||
enumerator->GetNext(getter_AddRefs(supports));
|
||||
nsCOMPtr<nsIDOMWindow> domWin(do_QueryInterface(supports));
|
||||
if (domWin) {
|
||||
nsresult rv2 = DispatchEventToWindow(domWin, eventType, tokenName);
|
||||
if (NS_FAILED(rv2)) {
|
||||
// return the last failure, don't let a single failure prevent
|
||||
// continued delivery of events.
|
||||
rv = rv2;
|
||||
}
|
||||
}
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsNSSComponent::DispatchEventToWindow(nsIDOMWindow *domWin,
|
||||
const nsAString &eventType, const nsAString &tokenName)
|
||||
{
|
||||
// first walk the children and dispatch their events
|
||||
{
|
||||
nsresult rv;
|
||||
nsCOMPtr<nsIDOMWindowCollection> frames;
|
||||
rv = domWin->GetFrames(getter_AddRefs(frames));
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
PRUint32 length;
|
||||
frames->GetLength(&length);
|
||||
PRUint32 i;
|
||||
for (i = 0; i < length; i++) {
|
||||
nsCOMPtr<nsIDOMWindow> childWin;
|
||||
frames->Item(i, getter_AddRefs(childWin));
|
||||
DispatchEventToWindow(childWin, eventType, tokenName);
|
||||
}
|
||||
}
|
||||
|
||||
// check if we've enabled smart card events on this window
|
||||
// NOTE: it's not an error to say that we aren't going to dispatch
|
||||
// the event.
|
||||
{
|
||||
nsCOMPtr<nsIDOMWindowInternal> intWindow = do_QueryInterface(domWin);
|
||||
if (!intWindow) {
|
||||
return NS_OK; // nope, it's not an internal window
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIDOMCrypto> crypto;
|
||||
intWindow->GetCrypto(getter_AddRefs(crypto));
|
||||
if (!crypto) {
|
||||
return NS_OK; // nope, it doesn't have a crypto property
|
||||
}
|
||||
|
||||
PRBool boolrv;
|
||||
crypto->GetEnableSmartCardEvents(&boolrv);
|
||||
if (!boolrv) {
|
||||
return NS_OK; // nope, it's not enabled.
|
||||
}
|
||||
}
|
||||
|
||||
// dispatch the event ...
|
||||
|
||||
nsresult rv;
|
||||
// find the document
|
||||
nsCOMPtr<nsIDOMDocument> doc;
|
||||
rv = domWin->GetDocument(getter_AddRefs(doc));
|
||||
if (doc == nsnull) {
|
||||
return NS_FAILED(rv) ? rv : NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
// create the event
|
||||
nsCOMPtr<nsIDOMDocumentEvent> docEvent = do_QueryInterface(doc, &rv);
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIDOMEvent> event;
|
||||
rv = docEvent->CreateEvent(NS_LITERAL_STRING("Events"),
|
||||
getter_AddRefs(event));
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
event->InitEvent(eventType, false, true);
|
||||
|
||||
// create the Smart Card Event;
|
||||
nsCOMPtr<nsIDOMSmartCardEvent> smartCardEvent =
|
||||
new nsSmartCardEvent(tokenName);
|
||||
// init the smart card event, fail here if we can't complete the
|
||||
// initialization.
|
||||
if (!smartCardEvent) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
rv = smartCardEvent->Init(event);
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
// Send it
|
||||
nsCOMPtr<nsIDOMEventTarget> target = do_QueryInterface(doc, &rv);
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
PRBool boolrv;
|
||||
rv = target->DispatchEvent(smartCardEvent, &boolrv);
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
||||
#ifdef XP_MAC
|
||||
#ifdef DEBUG
|
||||
#define LOADABLE_CERTS_MODULE NS_LITERAL_CSTRING("NSSckbiDebug.shlb")
|
||||
|
@ -355,6 +556,62 @@ nsNSSComponent::SkipOcspOff()
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
void
|
||||
nsNSSComponent::LaunchSmartCardThreads()
|
||||
{
|
||||
nsNSSShutDownPreventionLock locker;
|
||||
{
|
||||
SECMODModuleList *list = SECMOD_GetDefaultModuleList();
|
||||
SECMODListLock *lock = SECMOD_GetDefaultModuleListLock();
|
||||
SECMOD_GetReadLock(lock);
|
||||
|
||||
while (list) {
|
||||
SECMODModule *module = list->module;
|
||||
LaunchSmartCardThread(module);
|
||||
list = list->next;
|
||||
}
|
||||
SECMOD_ReleaseReadLock(lock);
|
||||
}
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsNSSComponent::LaunchSmartCardThread(SECMODModule *module)
|
||||
{
|
||||
SmartCardMonitoringThread *newThread;
|
||||
if (SECMOD_HasRemovableSlots(module)) {
|
||||
if (mThreadList == nsnull) {
|
||||
mThreadList = new SmartCardThreadList();
|
||||
if (!mThreadList) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
}
|
||||
newThread = new SmartCardMonitoringThread(module);
|
||||
if (!newThread) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
// newThread is adopted by the add.
|
||||
return mThreadList->Add(newThread);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsNSSComponent::ShutdownSmartCardThread(SECMODModule *module)
|
||||
{
|
||||
if (!mThreadList) {
|
||||
return NS_OK;
|
||||
}
|
||||
mThreadList->Remove(module);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void
|
||||
nsNSSComponent::ShutdownSmartCardThreads()
|
||||
{
|
||||
delete mThreadList;
|
||||
mThreadList = nsnull;
|
||||
}
|
||||
|
||||
void
|
||||
nsNSSComponent::InstallLoadableRoots()
|
||||
{
|
||||
|
@ -375,7 +632,7 @@ nsNSSComponent::InstallLoadableRoots()
|
|||
PK11SlotInfo *slot = module->slots[i];
|
||||
if (PK11_IsPresent(slot)) {
|
||||
if (PK11_HasRootCerts(slot)) {
|
||||
RootsModule = module;
|
||||
RootsModule = SECMOD_ReferenceModule(module);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -392,6 +649,7 @@ nsNSSComponent::InstallLoadableRoots()
|
|||
CK_INFO info;
|
||||
if (SECSuccess != PK11_GetModInfo(RootsModule, &info)) {
|
||||
// Do not use this module
|
||||
SECMOD_DestroyModule(RootsModule);
|
||||
RootsModule = nsnull;
|
||||
}
|
||||
else {
|
||||
|
@ -408,13 +666,16 @@ nsNSSComponent::InstallLoadableRoots()
|
|||
) {
|
||||
PRInt32 modType;
|
||||
SECMOD_DeleteModule(RootsModule->commonName, &modType);
|
||||
SECMOD_DestroyModule(RootsModule);
|
||||
|
||||
RootsModule = nsnull;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!RootsModule) {
|
||||
if (RootsModule) {
|
||||
SECMOD_DestroyModule(RootsModule);
|
||||
} else { /* !RootsModule */
|
||||
// Load roots module from our installation path
|
||||
|
||||
nsresult rv;
|
||||
|
@ -621,9 +882,9 @@ static void setOCSPOptions(nsIPrefBranch * pref)
|
|||
pref->GetIntPref("security.OCSP.enabled", &ocspEnabled);
|
||||
switch (ocspEnabled) {
|
||||
case 0:
|
||||
CERT_DisableOCSPChecking(CERT_GetDefaultCertDB());
|
||||
CERT_DisableOCSPDefaultResponder(CERT_GetDefaultCertDB());
|
||||
break;
|
||||
CERT_DisableOCSPChecking(CERT_GetDefaultCertDB());
|
||||
CERT_DisableOCSPDefaultResponder(CERT_GetDefaultCertDB());
|
||||
break;
|
||||
case 1:
|
||||
CERT_EnableOCSPChecking(CERT_GetDefaultCertDB());
|
||||
break;
|
||||
|
@ -644,15 +905,13 @@ static void setOCSPOptions(nsIPrefBranch * pref)
|
|||
nsMemory::Free(signingCA);
|
||||
nsMemory::Free(url);
|
||||
}
|
||||
break;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsNSSComponent::PostCRLImportEvent(nsCAutoString *urlString, PSMContentDownloader *psmDownloader)
|
||||
{
|
||||
nsresult rv;
|
||||
|
||||
//Create the event
|
||||
CRLDownloadEvent *event = new CRLDownloadEvent;
|
||||
PL_InitEvent(event, this, (PLHandleEventProc)HandleCRLImportPLEvent, (PLDestroyEventProc)DestroyCRLImportPLEvent);
|
||||
|
@ -660,17 +919,12 @@ nsNSSComponent::PostCRLImportEvent(nsCAutoString *urlString, PSMContentDownloade
|
|||
event->psmDownloader = (nsIStreamListener *)psmDownloader;
|
||||
|
||||
//Get a handle to the ui event queue
|
||||
nsCOMPtr<nsIEventQueueService> service =
|
||||
do_GetService(NS_EVENTQUEUESERVICE_CONTRACTID, &rv);
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
nsIEventQueue* result = nsnull;
|
||||
rv = service->GetThreadEventQueue(NS_UI_THREAD, &result);
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
nsCOMPtr<nsIEventQueue>uiQueue = dont_AddRef(result);
|
||||
nsCOMPtr<nsIEventQueue>uiQueue = nsNSSEventGetUIEventQueue();
|
||||
|
||||
if (!uiQueue) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
//Post the event
|
||||
return uiQueue->PostEvent(event);
|
||||
|
@ -1212,6 +1466,8 @@ nsNSSComponent::InitializeNSS(PRBool showWarningBox)
|
|||
|
||||
InstallLoadableRoots();
|
||||
|
||||
LaunchSmartCardThreads();
|
||||
|
||||
PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("NSS Initialization done\n"));
|
||||
}
|
||||
}
|
||||
|
@ -1258,6 +1514,7 @@ nsNSSComponent::ShutdownNSS()
|
|||
pbi->RemoveObserver("security.", this);
|
||||
}
|
||||
|
||||
ShutdownSmartCardThreads();
|
||||
SSL_ClearSessionCache();
|
||||
PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("evaporating psm resources\n"));
|
||||
mShutdownObjectList->evaporateAllNSSResources();
|
||||
|
|
|
@ -50,11 +50,13 @@
|
|||
#include "nsIEntropyCollector.h"
|
||||
#include "nsString.h"
|
||||
#include "nsIStringBundle.h"
|
||||
#include "nsIDOMEventTarget.h"
|
||||
#include "nsIPrefBranch.h"
|
||||
#include "nsIObserver.h"
|
||||
#include "nsIObserverService.h"
|
||||
#include "nsWeakReference.h"
|
||||
#include "nsIScriptSecurityManager.h"
|
||||
#include "nsSmartCardMonitor.h"
|
||||
#include "nsITimer.h"
|
||||
#include "nsNetUtil.h"
|
||||
#include "nsHashtable.h"
|
||||
|
@ -147,6 +149,14 @@ class NS_NO_VTABLE nsINSSComponent : public nsISupports {
|
|||
NS_IMETHOD DownloadCRLDirectly(nsAutoString, nsAutoString) = 0;
|
||||
|
||||
NS_IMETHOD LogoutAuthenticatedPK11() = 0;
|
||||
|
||||
NS_IMETHOD LaunchSmartCardThread(SECMODModule *module) = 0;
|
||||
|
||||
NS_IMETHOD ShutdownSmartCardThread(SECMODModule *module) = 0;
|
||||
|
||||
NS_IMETHOD PostEvent(const nsAString &eventType, const nsAString &token) = 0;
|
||||
|
||||
NS_IMETHOD DispatchEvent(const nsAString &eventType, const nsAString &token) = 0;
|
||||
|
||||
};
|
||||
|
||||
|
@ -205,6 +215,11 @@ public:
|
|||
NS_IMETHOD RememberCert(CERTCertificate *cert);
|
||||
static nsresult GetNSSCipherIDFromPrefString(const nsACString &aPrefString, PRUint16 &aCipherId);
|
||||
|
||||
NS_IMETHOD LaunchSmartCardThread(SECMODModule *module);
|
||||
NS_IMETHOD ShutdownSmartCardThread(SECMODModule *module);
|
||||
NS_IMETHOD PostEvent(const nsAString &eventType, const nsAString &token);
|
||||
NS_IMETHOD DispatchEvent(const nsAString &eventType, const nsAString &token);
|
||||
|
||||
private:
|
||||
|
||||
nsresult InitializeNSS(PRBool showWarningBox);
|
||||
|
@ -223,6 +238,8 @@ private:
|
|||
|
||||
void ShowAlert(AlertIdentifier ai);
|
||||
void InstallLoadableRoots();
|
||||
void LaunchSmartCardThreads();
|
||||
void ShutdownSmartCardThreads();
|
||||
nsresult InitializePIPNSSBundle();
|
||||
nsresult ConfigureInternalPKCS11Token();
|
||||
nsresult RegisterPSMContentListener();
|
||||
|
@ -230,6 +247,7 @@ private:
|
|||
nsresult DownloadCrlSilently();
|
||||
nsresult PostCRLImportEvent(nsCAutoString *urlString, PSMContentDownloader *psmDownloader);
|
||||
nsresult getParamsForNextCrlToDownload(nsAutoString *url, PRTime *time, nsAutoString *key);
|
||||
nsresult DispatchEventToWindow(nsIDOMWindow *domWin, const nsAString &eventType, const nsAString &token);
|
||||
PRLock *mutex;
|
||||
|
||||
nsCOMPtr<nsIScriptSecurityManager> mScriptSecurityManager;
|
||||
|
@ -248,6 +266,7 @@ private:
|
|||
PRBool mUpdateTimerInitialized;
|
||||
static int mInstanceCount;
|
||||
nsNSSShutDownList *mShutdownObjectList;
|
||||
SmartCardThreadList *mThreadList;
|
||||
};
|
||||
|
||||
class PSMContentListener : public nsIURIContentListener,
|
||||
|
|
|
@ -61,8 +61,16 @@ nsPK11Token::nsPK11Token(PK11SlotInfo *slot)
|
|||
|
||||
PK11_ReferenceSlot(slot);
|
||||
mSlot = slot;
|
||||
|
||||
mTokenName = NS_ConvertUTF8toUCS2(PK11_GetTokenName(slot));
|
||||
mSeries = PK11_GetSlotSeries(slot);
|
||||
|
||||
refreshTokenInfo();
|
||||
mUIContext = new PipUIContext();
|
||||
}
|
||||
|
||||
void
|
||||
nsPK11Token::refreshTokenInfo()
|
||||
{
|
||||
mTokenName = NS_ConvertUTF8toUTF16(PK11_GetTokenName(mSlot));
|
||||
|
||||
SECStatus srv;
|
||||
|
||||
|
@ -103,7 +111,6 @@ nsPK11Token::nsPK11Token(PK11SlotInfo *slot)
|
|||
mTokenSerialNum.Trim(" ", PR_FALSE, PR_TRUE);
|
||||
}
|
||||
|
||||
mUIContext = new PipUIContext();
|
||||
}
|
||||
|
||||
nsPK11Token::~nsPK11Token()
|
||||
|
@ -135,6 +142,10 @@ void nsPK11Token::destructorSafeDestroyNSSReference()
|
|||
/* readonly attribute wstring tokenName; */
|
||||
NS_IMETHODIMP nsPK11Token::GetTokenName(PRUnichar * *aTokenName)
|
||||
{
|
||||
// handle removals/insertions
|
||||
if (mSeries != PK11_GetSlotSeries(mSlot)) {
|
||||
refreshTokenInfo();
|
||||
}
|
||||
*aTokenName = ToNewUnicode(mTokenName);
|
||||
if (!*aTokenName) return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
|
@ -144,6 +155,10 @@ NS_IMETHODIMP nsPK11Token::GetTokenName(PRUnichar * *aTokenName)
|
|||
/* readonly attribute wstring tokenDesc; */
|
||||
NS_IMETHODIMP nsPK11Token::GetTokenLabel(PRUnichar **aTokLabel)
|
||||
{
|
||||
// handle removals/insertions
|
||||
if (mSeries != PK11_GetSlotSeries(mSlot)) {
|
||||
refreshTokenInfo();
|
||||
}
|
||||
*aTokLabel = ToNewUnicode(mTokenLabel);
|
||||
if (!*aTokLabel) return NS_ERROR_OUT_OF_MEMORY;
|
||||
return NS_OK;
|
||||
|
@ -152,6 +167,10 @@ NS_IMETHODIMP nsPK11Token::GetTokenLabel(PRUnichar **aTokLabel)
|
|||
/* readonly attribute wstring tokenManID; */
|
||||
NS_IMETHODIMP nsPK11Token::GetTokenManID(PRUnichar **aTokManID)
|
||||
{
|
||||
// handle removals/insertions
|
||||
if (mSeries != PK11_GetSlotSeries(mSlot)) {
|
||||
refreshTokenInfo();
|
||||
}
|
||||
*aTokManID = ToNewUnicode(mTokenManID);
|
||||
if (!*aTokManID) return NS_ERROR_OUT_OF_MEMORY;
|
||||
return NS_OK;
|
||||
|
@ -160,6 +179,10 @@ NS_IMETHODIMP nsPK11Token::GetTokenManID(PRUnichar **aTokManID)
|
|||
/* readonly attribute wstring tokenHWVersion; */
|
||||
NS_IMETHODIMP nsPK11Token::GetTokenHWVersion(PRUnichar **aTokHWVersion)
|
||||
{
|
||||
// handle removals/insertions
|
||||
if (mSeries != PK11_GetSlotSeries(mSlot)) {
|
||||
refreshTokenInfo();
|
||||
}
|
||||
*aTokHWVersion = ToNewUnicode(mTokenHWVersion);
|
||||
if (!*aTokHWVersion) return NS_ERROR_OUT_OF_MEMORY;
|
||||
return NS_OK;
|
||||
|
@ -168,6 +191,10 @@ NS_IMETHODIMP nsPK11Token::GetTokenHWVersion(PRUnichar **aTokHWVersion)
|
|||
/* readonly attribute wstring tokenFWVersion; */
|
||||
NS_IMETHODIMP nsPK11Token::GetTokenFWVersion(PRUnichar **aTokFWVersion)
|
||||
{
|
||||
// handle removals/insertions
|
||||
if (mSeries != PK11_GetSlotSeries(mSlot)) {
|
||||
refreshTokenInfo();
|
||||
}
|
||||
*aTokFWVersion = ToNewUnicode(mTokenFWVersion);
|
||||
if (!*aTokFWVersion) return NS_ERROR_OUT_OF_MEMORY;
|
||||
return NS_OK;
|
||||
|
@ -176,6 +203,10 @@ NS_IMETHODIMP nsPK11Token::GetTokenFWVersion(PRUnichar **aTokFWVersion)
|
|||
/* readonly attribute wstring tokenSerialNumber; */
|
||||
NS_IMETHODIMP nsPK11Token::GetTokenSerialNumber(PRUnichar **aTokSerialNum)
|
||||
{
|
||||
// handle removals/insertions
|
||||
if (mSeries != PK11_GetSlotSeries(mSlot)) {
|
||||
refreshTokenInfo();
|
||||
}
|
||||
*aTokSerialNum = ToNewUnicode(mTokenSerialNum);
|
||||
if (!*aTokSerialNum) return NS_ERROR_OUT_OF_MEMORY;
|
||||
return NS_OK;
|
||||
|
|
|
@ -63,11 +63,13 @@ public:
|
|||
|
||||
private:
|
||||
friend class nsPK11TokenDB;
|
||||
void refreshTokenInfo();
|
||||
|
||||
nsString mTokenName;
|
||||
nsString mTokenLabel, mTokenManID, mTokenHWVersion, mTokenFWVersion;
|
||||
nsString mTokenSerialNum;
|
||||
PK11SlotInfo *mSlot;
|
||||
int mSeries;
|
||||
nsCOMPtr<nsIInterfaceRequestor> mUIContext;
|
||||
virtual void virtualDestroyNSSReference();
|
||||
void destructorSafeDestroyNSSReference();
|
||||
|
|
|
@ -60,7 +60,13 @@ nsPKCS11Slot::nsPKCS11Slot(PK11SlotInfo *slot)
|
|||
|
||||
PK11_ReferenceSlot(slot);
|
||||
mSlot = slot;
|
||||
mSeries = PK11_GetSlotSeries(slot);
|
||||
refreshSlotInfo();
|
||||
}
|
||||
|
||||
void
|
||||
nsPKCS11Slot::refreshSlotInfo()
|
||||
{
|
||||
CK_SLOT_INFO slot_info;
|
||||
if (PK11_GetSlotInfo(mSlot, &slot_info) == SECSuccess) {
|
||||
// Set the Description field
|
||||
|
@ -78,10 +84,12 @@ nsPKCS11Slot::nsPKCS11Slot(PK11SlotInfo *slot)
|
|||
mSlotManID = NS_ConvertUTF8toUCS2(cManID);
|
||||
mSlotManID.Trim(" ", PR_FALSE, PR_TRUE);
|
||||
// Set the Hardware Version field
|
||||
mSlotHWVersion = EmptyString();
|
||||
mSlotHWVersion.AppendInt(slot_info.hardwareVersion.major);
|
||||
mSlotHWVersion.AppendLiteral(".");
|
||||
mSlotHWVersion.AppendInt(slot_info.hardwareVersion.minor);
|
||||
// Set the Firmware Version field
|
||||
mSlotFWVersion = EmptyString();
|
||||
mSlotFWVersion.AppendInt(slot_info.firmwareVersion.major);
|
||||
mSlotFWVersion.AppendLiteral(".");
|
||||
mSlotFWVersion.AppendInt(slot_info.firmwareVersion.minor);
|
||||
|
@ -127,7 +135,7 @@ nsPKCS11Slot::GetName(PRUnichar **aName)
|
|||
if (*csn) {
|
||||
*aName = ToNewUnicode(NS_ConvertUTF8toUCS2(csn));
|
||||
} else if (PK11_HasRootCerts(mSlot)) {
|
||||
// This is a workaround to an NSS bug - the root certs module has
|
||||
// This is a workaround to an Root Module bug - the root certs module has
|
||||
// no slot name. Not bothering to localize, because this is a workaround
|
||||
// and for now all the slot names returned by NSS are char * anyway.
|
||||
*aName = ToNewUnicode(NS_LITERAL_STRING("Root Certificates"));
|
||||
|
@ -147,6 +155,10 @@ nsPKCS11Slot::GetDesc(PRUnichar **aDesc)
|
|||
if (isAlreadyShutDown())
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
|
||||
if (mSeries != PK11_GetSlotSeries(mSlot)) {
|
||||
refreshSlotInfo();
|
||||
}
|
||||
|
||||
*aDesc = ToNewUnicode(mSlotDesc);
|
||||
if (!*aDesc) return NS_ERROR_OUT_OF_MEMORY;
|
||||
return NS_OK;
|
||||
|
@ -156,6 +168,9 @@ nsPKCS11Slot::GetDesc(PRUnichar **aDesc)
|
|||
NS_IMETHODIMP
|
||||
nsPKCS11Slot::GetManID(PRUnichar **aManID)
|
||||
{
|
||||
if (mSeries != PK11_GetSlotSeries(mSlot)) {
|
||||
refreshSlotInfo();
|
||||
}
|
||||
*aManID = ToNewUnicode(mSlotManID);
|
||||
if (!*aManID) return NS_ERROR_OUT_OF_MEMORY;
|
||||
return NS_OK;
|
||||
|
@ -165,6 +180,9 @@ nsPKCS11Slot::GetManID(PRUnichar **aManID)
|
|||
NS_IMETHODIMP
|
||||
nsPKCS11Slot::GetHWVersion(PRUnichar **aHWVersion)
|
||||
{
|
||||
if (mSeries != PK11_GetSlotSeries(mSlot)) {
|
||||
refreshSlotInfo();
|
||||
}
|
||||
*aHWVersion = ToNewUnicode(mSlotHWVersion);
|
||||
if (!*aHWVersion) return NS_ERROR_OUT_OF_MEMORY;
|
||||
return NS_OK;
|
||||
|
@ -174,6 +192,9 @@ nsPKCS11Slot::GetHWVersion(PRUnichar **aHWVersion)
|
|||
NS_IMETHODIMP
|
||||
nsPKCS11Slot::GetFWVersion(PRUnichar **aFWVersion)
|
||||
{
|
||||
if (mSeries != PK11_GetSlotSeries(mSlot)) {
|
||||
refreshSlotInfo();
|
||||
}
|
||||
*aFWVersion = ToNewUnicode(mSlotFWVersion);
|
||||
if (!*aFWVersion) return NS_ERROR_OUT_OF_MEMORY;
|
||||
return NS_OK;
|
||||
|
@ -203,6 +224,16 @@ nsPKCS11Slot::GetTokenName(PRUnichar **aName)
|
|||
if (isAlreadyShutDown())
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
|
||||
if (!PK11_IsPresent(mSlot)) {
|
||||
*aName = nsnull;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
if (mSeries != PK11_GetSlotSeries(mSlot)) {
|
||||
refreshSlotInfo();
|
||||
}
|
||||
|
||||
|
||||
*aName = ToNewUnicode(NS_ConvertUTF8toUCS2(PK11_GetTokenName(mSlot)));
|
||||
if (!*aName) return NS_ERROR_OUT_OF_MEMORY;
|
||||
return NS_OK;
|
||||
|
@ -305,30 +336,35 @@ nsPKCS11Module::FindSlotByName(const PRUnichar *aName,
|
|||
if (isAlreadyShutDown())
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
|
||||
char *asciiname = NULL;
|
||||
asciiname = ToNewUTF8String(nsDependentString(aName));
|
||||
char *asciiname = ToNewUTF8String(nsDependentString(aName));
|
||||
PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("Getting \"%s\"\n", asciiname));
|
||||
PK11SlotInfo *slotinfo = SECMOD_FindSlot(mModule, asciiname);
|
||||
if (!slotinfo) {
|
||||
// XXX *sigh* if token is present, SECMOD_FindSlot goes by token
|
||||
// name (huh?) reimplement it here for the fun of it.
|
||||
for (int i=0; i<mModule->slotCount; i++) {
|
||||
if (nsCRT::strcmp(asciiname, PK11_GetSlotName(mModule->slots[i])) == 0) {
|
||||
slotinfo = PK11_ReferenceSlot(mModule->slots[i]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!slotinfo) {
|
||||
// XXX another workaround - the builtin module has no name
|
||||
if (nsCRT::strcmp(asciiname, "Root Certificates") == 0) {
|
||||
slotinfo = PK11_ReferenceSlot(mModule->slots[0]);
|
||||
} else {
|
||||
// give up
|
||||
nsMemory::Free(asciiname);
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
}
|
||||
PK11SlotInfo *slotinfo = NULL;
|
||||
PK11SlotList *slotList = PK11_FindSlotsByNames(mModule->dllName,
|
||||
asciiname /* slotName */, NULL /* token Name */, PR_FALSE);
|
||||
if (!slotList) {
|
||||
/* name must be the token name */
|
||||
slotList = PK11_FindSlotsByNames(mModule->dllName,
|
||||
NULL /*slot Name */, asciiname /* token Name */, PR_FALSE);
|
||||
}
|
||||
if (slotList) {
|
||||
/* should only be one */
|
||||
if (slotList->head && slotList->head->slot) {
|
||||
slotinfo = PK11_ReferenceSlot(slotList->head->slot);
|
||||
}
|
||||
PK11_FreeSlotList(slotList);
|
||||
}
|
||||
if (!slotinfo) {
|
||||
// workaround - the builtin module has no name
|
||||
if (asciiname == nsnull) {
|
||||
return NS_ERROR_FAILURE;
|
||||
} else if (nsCRT::strcmp(asciiname, "Root Certificates") == 0) {
|
||||
slotinfo = PK11_ReferenceSlot(mModule->slots[0]);
|
||||
} else {
|
||||
// give up
|
||||
nsMemory::Free(asciiname);
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
}
|
||||
nsMemory::Free(asciiname);
|
||||
nsCOMPtr<nsIPKCS11Slot> slot = new nsPKCS11Slot(slotinfo);
|
||||
PK11_FreeSlot(slotinfo);
|
||||
|
@ -353,12 +389,19 @@ nsPKCS11Module::ListSlots(nsIEnumerator **_retval)
|
|||
nsCOMPtr<nsISupportsArray> array;
|
||||
rv = NS_NewISupportsArray(getter_AddRefs(array));
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
/* applications which allow new slot creation (which Firefox now does
|
||||
* since it uses the WaitForSlotEvent call) need to hold the
|
||||
* ModuleList Read lock to prevent the slot array from changing out
|
||||
* from under it. */
|
||||
SECMODListLock *lock = SECMOD_GetDefaultModuleListLock();
|
||||
SECMOD_GetReadLock(lock);
|
||||
for (i=0; i<mModule->slotCount; i++) {
|
||||
if (mModule->slots[i]) {
|
||||
nsCOMPtr<nsIPKCS11Slot> slot = new nsPKCS11Slot(mModule->slots[i]);
|
||||
array->AppendElement(slot);
|
||||
}
|
||||
}
|
||||
SECMOD_ReleaseReadLock(lock);
|
||||
rv = array->Enumerate(_retval);
|
||||
return rv;
|
||||
}
|
||||
|
@ -468,6 +511,13 @@ nsPKCS11ModuleDB::ListModules(nsIEnumerator **_retval)
|
|||
array->AppendElement(module);
|
||||
list = list->next;
|
||||
}
|
||||
/* Get the modules in the database that didn't load */
|
||||
list = SECMOD_GetDeadModuleList();
|
||||
while (list) {
|
||||
nsCOMPtr<nsIPKCS11Module> module = new nsPKCS11Module(list->module);
|
||||
array->AppendElement(module);
|
||||
list = list->next;
|
||||
}
|
||||
SECMOD_ReleaseReadLock(lock);
|
||||
rv = array->Enumerate(_retval);
|
||||
return rv;
|
||||
|
|
|
@ -63,9 +63,11 @@ private:
|
|||
|
||||
PK11SlotInfo *mSlot;
|
||||
nsString mSlotDesc, mSlotManID, mSlotHWVersion, mSlotFWVersion;
|
||||
int mSeries;
|
||||
|
||||
virtual void virtualDestroyNSSReference();
|
||||
void destructorSafeDestroyNSSReference();
|
||||
void refreshSlotInfo();
|
||||
};
|
||||
|
||||
class nsPKCS11Module : public nsIPKCS11Module,
|
||||
|
|
Загрузка…
Ссылка в новой задаче