2
* The contents of this file are subject to the Mozilla Public
3
* License Version 1.1 (the "License"); you may not use this file
4
* except in compliance with the License. You may obtain a copy of
5
* the License at http://www.mozilla.org/MPL/
7
* Software distributed under the License is distributed on an "AS
8
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
9
* implied. See the License for the specific language governing
10
* rights and limitations under the License.
12
* The Original Code is the Netscape security libraries.
14
* The Initial Developer of the Original Code is Netscape
15
* Communications Corporation. Portions created by Netscape are
16
* Copyright (C) 2000 Netscape Communications Corporation. All
20
* Ian McGreer <mcgreer@netscape.com>
22
* Alternatively, the contents of this file may be used under the
23
* terms of the GNU General Public License Version 2 or later (the
24
* "GPL"), in which case the provisions of the GPL are applicable
25
* instead of those above. If you wish to allow use of your
26
* version of this file only under the terms of the GPL and not to
27
* allow others to use your version of this file under the MPL,
28
* indicate your decision by deleting the provisions above and
29
* replace them with the notice and other provisions required by
30
* the GPL. If you do not delete the provisions above, a recipient
31
* may use your version of this file under either the MPL or the
36
#include "nsPKCS11Slot.h"
37
#include "nsPK11TokenDB.h"
40
#include "nsISupportsArray.h"
42
#include "nsReadableUtils.h"
48
extern PRLogModuleInfo* gPIPNSSLog;
51
NS_IMPL_ISUPPORTS1(nsPKCS11Slot, nsIPKCS11Slot)
53
nsPKCS11Slot::nsPKCS11Slot(PK11SlotInfo *slot)
55
nsNSSShutDownPreventionLock locker;
56
if (isAlreadyShutDown())
59
PK11_ReferenceSlot(slot);
62
CK_SLOT_INFO slot_info;
63
if (PK11_GetSlotInfo(mSlot, &slot_info) == SECSuccess) {
64
// Set the Description field
65
const char *ccDesc = (const char*)slot_info.slotDescription;
66
const nsACString &cDesc = Substring(
68
ccDesc+PL_strnlen(ccDesc, sizeof(slot_info.slotDescription)));
69
mSlotDesc = NS_ConvertUTF8toUCS2(cDesc);
70
mSlotDesc.Trim(" ", PR_FALSE, PR_TRUE);
71
// Set the Manufacturer field
72
const char *ccManID = (const char*)slot_info.manufacturerID;
73
const nsACString &cManID = Substring(
75
ccManID+PL_strnlen(ccManID, sizeof(slot_info.manufacturerID)));
76
mSlotManID = NS_ConvertUTF8toUCS2(cManID);
77
mSlotManID.Trim(" ", PR_FALSE, PR_TRUE);
78
// Set the Hardware Version field
79
mSlotHWVersion.AppendInt(slot_info.hardwareVersion.major);
80
mSlotHWVersion.Append(NS_LITERAL_STRING("."));
81
mSlotHWVersion.AppendInt(slot_info.hardwareVersion.minor);
82
// Set the Firmware Version field
83
mSlotFWVersion.AppendInt(slot_info.firmwareVersion.major);
84
mSlotFWVersion.Append(NS_LITERAL_STRING("."));
85
mSlotFWVersion.AppendInt(slot_info.firmwareVersion.minor);
90
nsPKCS11Slot::~nsPKCS11Slot()
92
nsNSSShutDownPreventionLock locker;
93
if (isAlreadyShutDown())
96
destructorSafeDestroyNSSReference();
97
shutdown(calledFromObject);
100
void nsPKCS11Slot::virtualDestroyNSSReference()
102
destructorSafeDestroyNSSReference();
105
void nsPKCS11Slot::destructorSafeDestroyNSSReference()
107
if (isAlreadyShutDown())
111
PK11_FreeSlot(mSlot);
116
/* readonly attribute wstring name; */
118
nsPKCS11Slot::GetName(PRUnichar **aName)
120
nsNSSShutDownPreventionLock locker;
121
if (isAlreadyShutDown())
122
return NS_ERROR_NOT_AVAILABLE;
124
char *csn = PK11_GetSlotName(mSlot);
126
*aName = ToNewUnicode(NS_ConvertUTF8toUCS2(csn));
127
} else if (PK11_HasRootCerts(mSlot)) {
128
// This is a workaround to an NSS bug - the root certs module has
129
// no slot name. Not bothering to localize, because this is a workaround
130
// and for now all the slot names returned by NSS are char * anyway.
131
*aName = ToNewUnicode(NS_LITERAL_STRING("Root Certificates"));
133
// same as above, this is a catch-all
134
*aName = ToNewUnicode(NS_LITERAL_STRING("Unnamed Slot"));
136
if (!*aName) return NS_ERROR_OUT_OF_MEMORY;
140
/* readonly attribute wstring desc; */
142
nsPKCS11Slot::GetDesc(PRUnichar **aDesc)
144
nsNSSShutDownPreventionLock locker;
145
if (isAlreadyShutDown())
146
return NS_ERROR_NOT_AVAILABLE;
148
*aDesc = ToNewUnicode(mSlotDesc);
149
if (!*aDesc) return NS_ERROR_OUT_OF_MEMORY;
153
/* readonly attribute wstring manID; */
155
nsPKCS11Slot::GetManID(PRUnichar **aManID)
157
*aManID = ToNewUnicode(mSlotManID);
158
if (!*aManID) return NS_ERROR_OUT_OF_MEMORY;
162
/* readonly attribute wstring HWVersion; */
164
nsPKCS11Slot::GetHWVersion(PRUnichar **aHWVersion)
166
*aHWVersion = ToNewUnicode(mSlotHWVersion);
167
if (!*aHWVersion) return NS_ERROR_OUT_OF_MEMORY;
171
/* readonly attribute wstring FWVersion; */
173
nsPKCS11Slot::GetFWVersion(PRUnichar **aFWVersion)
175
*aFWVersion = ToNewUnicode(mSlotFWVersion);
176
if (!*aFWVersion) return NS_ERROR_OUT_OF_MEMORY;
180
/* nsIPK11Token getToken (); */
182
nsPKCS11Slot::GetToken(nsIPK11Token **_retval)
184
nsNSSShutDownPreventionLock locker;
185
if (isAlreadyShutDown())
186
return NS_ERROR_NOT_AVAILABLE;
188
nsCOMPtr<nsIPK11Token> token = new nsPK11Token(mSlot);
190
return NS_ERROR_OUT_OF_MEMORY;
196
/* readonly attribute wstring tokenName; */
198
nsPKCS11Slot::GetTokenName(PRUnichar **aName)
200
nsNSSShutDownPreventionLock locker;
201
if (isAlreadyShutDown())
202
return NS_ERROR_NOT_AVAILABLE;
204
*aName = ToNewUnicode(NS_ConvertUTF8toUCS2(PK11_GetTokenName(mSlot)));
205
if (!*aName) return NS_ERROR_OUT_OF_MEMORY;
210
nsPKCS11Slot::GetStatus(PRUint32 *_retval)
212
nsNSSShutDownPreventionLock locker;
213
if (isAlreadyShutDown())
214
return NS_ERROR_NOT_AVAILABLE;
216
if (PK11_IsDisabled(mSlot))
217
*_retval = SLOT_DISABLED;
218
else if (!PK11_IsPresent(mSlot))
219
*_retval = SLOT_NOT_PRESENT;
220
else if (PK11_NeedLogin(mSlot) && PK11_NeedUserInit(mSlot))
221
*_retval = SLOT_UNINITIALIZED;
222
else if (PK11_NeedLogin(mSlot) && !PK11_IsLoggedIn(mSlot, NULL))
223
*_retval = SLOT_NOT_LOGGED_IN;
224
else if (PK11_NeedLogin(mSlot))
225
*_retval = SLOT_LOGGED_IN;
227
*_retval = SLOT_READY;
231
NS_IMPL_ISUPPORTS1(nsPKCS11Module, nsIPKCS11Module)
233
nsPKCS11Module::nsPKCS11Module(SECMODModule *module)
235
nsNSSShutDownPreventionLock locker;
236
if (isAlreadyShutDown())
239
SECMOD_ReferenceModule(module);
243
nsPKCS11Module::~nsPKCS11Module()
245
nsNSSShutDownPreventionLock locker;
246
if (isAlreadyShutDown())
249
destructorSafeDestroyNSSReference();
250
shutdown(calledFromObject);
253
void nsPKCS11Module::virtualDestroyNSSReference()
255
destructorSafeDestroyNSSReference();
258
void nsPKCS11Module::destructorSafeDestroyNSSReference()
260
if (isAlreadyShutDown())
264
SECMOD_DestroyModule(mModule);
269
/* readonly attribute wstring name; */
271
nsPKCS11Module::GetName(PRUnichar **aName)
273
nsNSSShutDownPreventionLock locker;
274
if (isAlreadyShutDown())
275
return NS_ERROR_NOT_AVAILABLE;
277
*aName = ToNewUnicode(NS_ConvertUTF8toUCS2(mModule->commonName));
281
/* readonly attribute wstring libName; */
283
nsPKCS11Module::GetLibName(PRUnichar **aName)
285
nsNSSShutDownPreventionLock locker;
286
if (isAlreadyShutDown())
287
return NS_ERROR_NOT_AVAILABLE;
289
if ( mModule->dllName ) {
290
*aName = ToNewUnicode(NS_ConvertUTF8toUCS2(mModule->dllName));
297
/* nsIPKCS11Slot findSlotByName(in wstring name); */
299
nsPKCS11Module::FindSlotByName(const PRUnichar *aName,
300
nsIPKCS11Slot **_retval)
302
nsNSSShutDownPreventionLock locker;
303
if (isAlreadyShutDown())
304
return NS_ERROR_NOT_AVAILABLE;
306
char *asciiname = NULL;
307
asciiname = ToNewUTF8String(nsDependentString(aName));
308
PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("Getting \"%s\"\n", asciiname));
309
PK11SlotInfo *slotinfo = SECMOD_FindSlot(mModule, asciiname);
311
// XXX *sigh* if token is present, SECMOD_FindSlot goes by token
312
// name (huh?) reimplement it here for the fun of it.
313
for (int i=0; i<mModule->slotCount; i++) {
314
if (nsCRT::strcmp(asciiname, PK11_GetSlotName(mModule->slots[i])) == 0) {
315
slotinfo = PK11_ReferenceSlot(mModule->slots[i]);
320
// XXX another workaround - the builtin module has no name
321
if (nsCRT::strcmp(asciiname, "Root Certificates") == 0) {
322
slotinfo = PK11_ReferenceSlot(mModule->slots[0]);
325
nsMemory::Free(asciiname);
326
return NS_ERROR_FAILURE;
330
nsMemory::Free(asciiname);
331
nsCOMPtr<nsIPKCS11Slot> slot = new nsPKCS11Slot(slotinfo);
332
PK11_FreeSlot(slotinfo);
334
return NS_ERROR_OUT_OF_MEMORY;
340
/* nsIEnumerator listSlots (); */
342
nsPKCS11Module::ListSlots(nsIEnumerator **_retval)
344
nsNSSShutDownPreventionLock locker;
345
if (isAlreadyShutDown())
346
return NS_ERROR_NOT_AVAILABLE;
350
/* get isupports array */
351
nsCOMPtr<nsISupportsArray> array;
352
rv = NS_NewISupportsArray(getter_AddRefs(array));
353
if (NS_FAILED(rv)) return rv;
354
for (i=0; i<mModule->slotCount; i++) {
355
if (mModule->slots[i]) {
356
nsCOMPtr<nsIPKCS11Slot> slot = new nsPKCS11Slot(mModule->slots[i]);
357
array->AppendElement(slot);
360
rv = array->Enumerate(_retval);
364
NS_IMPL_ISUPPORTS2(nsPKCS11ModuleDB, nsIPKCS11ModuleDB, nsICryptoFIPSInfo)
366
nsPKCS11ModuleDB::nsPKCS11ModuleDB()
370
nsPKCS11ModuleDB::~nsPKCS11ModuleDB()
374
/* nsIPKCS11Module getInternal (); */
376
nsPKCS11ModuleDB::GetInternal(nsIPKCS11Module **_retval)
378
nsNSSShutDownPreventionLock locker;
379
SECMODModule *nssMod =
380
SECMOD_CreateModule(NULL,SECMOD_INT_NAME, NULL,SECMOD_INT_FLAGS);
381
nsCOMPtr<nsIPKCS11Module> module = new nsPKCS11Module(nssMod);
382
SECMOD_DestroyModule(nssMod);
384
return NS_ERROR_OUT_OF_MEMORY;
390
/* nsIPKCS11Module getInternalFIPS (); */
392
nsPKCS11ModuleDB::GetInternalFIPS(nsIPKCS11Module **_retval)
394
nsNSSShutDownPreventionLock locker;
395
SECMODModule *nssMod =
396
SECMOD_CreateModule(NULL, SECMOD_FIPS_NAME, NULL, SECMOD_FIPS_FLAGS);
397
nsCOMPtr<nsIPKCS11Module> module = new nsPKCS11Module(nssMod);
398
SECMOD_DestroyModule(nssMod);
400
return NS_ERROR_OUT_OF_MEMORY;
406
/* nsIPKCS11Module findModuleByName(in wstring name); */
408
nsPKCS11ModuleDB::FindModuleByName(const PRUnichar *aName,
409
nsIPKCS11Module **_retval)
411
nsNSSShutDownPreventionLock locker;
412
NS_ConvertUCS2toUTF8 aUtf8Name(aName);
414
SECMOD_FindModule(NS_CONST_CAST(char *, aUtf8Name.get()));
416
return NS_ERROR_FAILURE;
417
nsCOMPtr<nsIPKCS11Module> module = new nsPKCS11Module(mod);
418
SECMOD_DestroyModule(mod);
420
return NS_ERROR_OUT_OF_MEMORY;
426
/* This is essentially the same as nsIPK11Token::findTokenByName, except
427
* that it returns an nsIPKCS11Slot, which may be desired.
429
/* nsIPKCS11Module findSlotByName(in wstring name); */
431
nsPKCS11ModuleDB::FindSlotByName(const PRUnichar *aName,
432
nsIPKCS11Slot **_retval)
434
nsNSSShutDownPreventionLock locker;
435
NS_ConvertUCS2toUTF8 aUtf8Name(aName);
436
PK11SlotInfo *slotinfo =
437
PK11_FindSlotByName(NS_CONST_CAST(char*, aUtf8Name.get()));
439
return NS_ERROR_FAILURE;
440
nsCOMPtr<nsIPKCS11Slot> slot = new nsPKCS11Slot(slotinfo);
441
PK11_FreeSlot(slotinfo);
443
return NS_ERROR_OUT_OF_MEMORY;
449
/* nsIEnumerator listModules (); */
451
nsPKCS11ModuleDB::ListModules(nsIEnumerator **_retval)
453
nsNSSShutDownPreventionLock locker;
455
/* get isupports array */
456
nsCOMPtr<nsISupportsArray> array;
457
rv = NS_NewISupportsArray(getter_AddRefs(array));
458
if (NS_FAILED(rv)) return rv;
459
/* get the default list of modules */
460
SECMODModuleList *list = SECMOD_GetDefaultModuleList();
461
/* lock down the list for reading */
462
SECMODListLock *lock = SECMOD_GetDefaultModuleListLock();
463
SECMOD_GetReadLock(lock);
465
nsCOMPtr<nsIPKCS11Module> module = new nsPKCS11Module(list->module);
466
array->AppendElement(module);
469
SECMOD_ReleaseReadLock(lock);
470
rv = array->Enumerate(_retval);
474
NS_IMETHODIMP nsPKCS11ModuleDB::GetCanToggleFIPS(PRBool *aCanToggleFIPS)
476
nsNSSShutDownPreventionLock locker;
477
*aCanToggleFIPS = SECMOD_CanDeleteInternalModule();
482
/* void toggleFIPSMode (); */
483
NS_IMETHODIMP nsPKCS11ModuleDB::ToggleFIPSMode()
485
nsNSSShutDownPreventionLock locker;
486
// The way to toggle FIPS mode in NSS is extremely obscure.
487
// Basically, we delete the internal module, and voila it
488
// gets replaced with the opposite module, ie if it was
489
// FIPS before, then it becomes non-FIPS next.
490
SECMODModule *internal;
492
// This function returns us a pointer to a local copy of
493
// the internal module stashed in NSS. We don't want to
494
// delete it since it will cause much pain in NSS.
495
internal = SECMOD_GetInternalModule();
497
return NS_ERROR_FAILURE;
499
SECStatus srv = SECMOD_DeleteInternalModule(internal->commonName);
500
if (srv != SECSuccess)
501
return NS_ERROR_FAILURE;
506
/* readonly attribute boolean isFIPSEnabled; */
507
NS_IMETHODIMP nsPKCS11ModuleDB::GetIsFIPSEnabled(PRBool *aIsFIPSEnabled)
509
nsNSSShutDownPreventionLock locker;
510
*aIsFIPSEnabled = PK11_IsFIPS();
514
NS_IMETHODIMP nsPKCS11ModuleDB::GetIsFIPSModeActive(PRBool *aIsFIPSModeActive)
516
return GetIsFIPSEnabled(aIsFIPSModeActive);