security/manager/ssl/src/nsPK11TokenDB.cpp

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

michael@0 1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
michael@0 2 *
michael@0 3 * This Source Code Form is subject to the terms of the Mozilla Public
michael@0 4 * License, v. 2.0. If a copy of the MPL was not distributed with this
michael@0 5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
michael@0 6 #include "nsISupports.h"
michael@0 7 #include "nsISupportsArray.h"
michael@0 8 #include "nsIPK11TokenDB.h"
michael@0 9 #include "prerror.h"
michael@0 10 #include "secerr.h"
michael@0 11 #include "nsReadableUtils.h"
michael@0 12 #include "nsNSSComponent.h"
michael@0 13 #include "nsServiceManagerUtils.h"
michael@0 14
michael@0 15 #include "nsPK11TokenDB.h"
michael@0 16
michael@0 17 #ifdef PR_LOGGING
michael@0 18 extern PRLogModuleInfo* gPIPNSSLog;
michael@0 19 #endif
michael@0 20
michael@0 21 NS_IMPL_ISUPPORTS(nsPK11Token, nsIPK11Token)
michael@0 22
michael@0 23 nsPK11Token::nsPK11Token(PK11SlotInfo *slot)
michael@0 24 {
michael@0 25 nsNSSShutDownPreventionLock locker;
michael@0 26 if (isAlreadyShutDown())
michael@0 27 return;
michael@0 28
michael@0 29 PK11_ReferenceSlot(slot);
michael@0 30 mSlot = slot;
michael@0 31 mSeries = PK11_GetSlotSeries(slot);
michael@0 32
michael@0 33 refreshTokenInfo();
michael@0 34 mUIContext = new PipUIContext();
michael@0 35 }
michael@0 36
michael@0 37 void
michael@0 38 nsPK11Token::refreshTokenInfo()
michael@0 39 {
michael@0 40 mTokenName = NS_ConvertUTF8toUTF16(PK11_GetTokenName(mSlot));
michael@0 41
michael@0 42 SECStatus srv;
michael@0 43
michael@0 44 CK_TOKEN_INFO tok_info;
michael@0 45 srv = PK11_GetTokenInfo(mSlot, &tok_info);
michael@0 46 if (srv == SECSuccess) {
michael@0 47 // Set the Label field
michael@0 48
michael@0 49 const char *ccLabel = (const char*)tok_info.label;
michael@0 50 const nsACString &cLabel = Substring(
michael@0 51 ccLabel,
michael@0 52 ccLabel+PL_strnlen(ccLabel, sizeof(tok_info.label)));
michael@0 53 mTokenLabel = NS_ConvertUTF8toUTF16(cLabel);
michael@0 54 mTokenLabel.Trim(" ", false, true);
michael@0 55
michael@0 56 // Set the Manufacturer field
michael@0 57 const char *ccManID = (const char*)tok_info.manufacturerID;
michael@0 58 const nsACString &cManID = Substring(
michael@0 59 ccManID,
michael@0 60 ccManID+PL_strnlen(ccManID, sizeof(tok_info.manufacturerID)));
michael@0 61 mTokenManID = NS_ConvertUTF8toUTF16(cManID);
michael@0 62 mTokenManID.Trim(" ", false, true);
michael@0 63
michael@0 64 // Set the Hardware Version field
michael@0 65 mTokenHWVersion.AppendInt(tok_info.hardwareVersion.major);
michael@0 66 mTokenHWVersion.AppendLiteral(".");
michael@0 67 mTokenHWVersion.AppendInt(tok_info.hardwareVersion.minor);
michael@0 68 // Set the Firmware Version field
michael@0 69 mTokenFWVersion.AppendInt(tok_info.firmwareVersion.major);
michael@0 70 mTokenFWVersion.AppendLiteral(".");
michael@0 71 mTokenFWVersion.AppendInt(tok_info.firmwareVersion.minor);
michael@0 72 // Set the Serial Number field
michael@0 73 const char *ccSerial = (const char*)tok_info.serialNumber;
michael@0 74 const nsACString &cSerial = Substring(
michael@0 75 ccSerial,
michael@0 76 ccSerial+PL_strnlen(ccSerial, sizeof(tok_info.serialNumber)));
michael@0 77 mTokenSerialNum = NS_ConvertUTF8toUTF16(cSerial);
michael@0 78 mTokenSerialNum.Trim(" ", false, true);
michael@0 79 }
michael@0 80
michael@0 81 }
michael@0 82
michael@0 83 nsPK11Token::~nsPK11Token()
michael@0 84 {
michael@0 85 nsNSSShutDownPreventionLock locker;
michael@0 86 if (isAlreadyShutDown()) {
michael@0 87 return;
michael@0 88 }
michael@0 89 destructorSafeDestroyNSSReference();
michael@0 90 shutdown(calledFromObject);
michael@0 91 }
michael@0 92
michael@0 93 void nsPK11Token::virtualDestroyNSSReference()
michael@0 94 {
michael@0 95 destructorSafeDestroyNSSReference();
michael@0 96 }
michael@0 97
michael@0 98 void nsPK11Token::destructorSafeDestroyNSSReference()
michael@0 99 {
michael@0 100 if (mSlot) {
michael@0 101 PK11_FreeSlot(mSlot);
michael@0 102 mSlot = nullptr;
michael@0 103 }
michael@0 104 }
michael@0 105
michael@0 106 /* readonly attribute wstring tokenName; */
michael@0 107 NS_IMETHODIMP nsPK11Token::GetTokenName(char16_t * *aTokenName)
michael@0 108 {
michael@0 109 // handle removals/insertions
michael@0 110 if (mSeries != PK11_GetSlotSeries(mSlot)) {
michael@0 111 refreshTokenInfo();
michael@0 112 }
michael@0 113 *aTokenName = ToNewUnicode(mTokenName);
michael@0 114 if (!*aTokenName) return NS_ERROR_OUT_OF_MEMORY;
michael@0 115
michael@0 116 return NS_OK;
michael@0 117 }
michael@0 118
michael@0 119 /* readonly attribute wstring tokenDesc; */
michael@0 120 NS_IMETHODIMP nsPK11Token::GetTokenLabel(char16_t **aTokLabel)
michael@0 121 {
michael@0 122 // handle removals/insertions
michael@0 123 if (mSeries != PK11_GetSlotSeries(mSlot)) {
michael@0 124 refreshTokenInfo();
michael@0 125 }
michael@0 126 *aTokLabel = ToNewUnicode(mTokenLabel);
michael@0 127 if (!*aTokLabel) return NS_ERROR_OUT_OF_MEMORY;
michael@0 128 return NS_OK;
michael@0 129 }
michael@0 130
michael@0 131 /* readonly attribute wstring tokenManID; */
michael@0 132 NS_IMETHODIMP nsPK11Token::GetTokenManID(char16_t **aTokManID)
michael@0 133 {
michael@0 134 // handle removals/insertions
michael@0 135 if (mSeries != PK11_GetSlotSeries(mSlot)) {
michael@0 136 refreshTokenInfo();
michael@0 137 }
michael@0 138 *aTokManID = ToNewUnicode(mTokenManID);
michael@0 139 if (!*aTokManID) return NS_ERROR_OUT_OF_MEMORY;
michael@0 140 return NS_OK;
michael@0 141 }
michael@0 142
michael@0 143 /* readonly attribute wstring tokenHWVersion; */
michael@0 144 NS_IMETHODIMP nsPK11Token::GetTokenHWVersion(char16_t **aTokHWVersion)
michael@0 145 {
michael@0 146 // handle removals/insertions
michael@0 147 if (mSeries != PK11_GetSlotSeries(mSlot)) {
michael@0 148 refreshTokenInfo();
michael@0 149 }
michael@0 150 *aTokHWVersion = ToNewUnicode(mTokenHWVersion);
michael@0 151 if (!*aTokHWVersion) return NS_ERROR_OUT_OF_MEMORY;
michael@0 152 return NS_OK;
michael@0 153 }
michael@0 154
michael@0 155 /* readonly attribute wstring tokenFWVersion; */
michael@0 156 NS_IMETHODIMP nsPK11Token::GetTokenFWVersion(char16_t **aTokFWVersion)
michael@0 157 {
michael@0 158 // handle removals/insertions
michael@0 159 if (mSeries != PK11_GetSlotSeries(mSlot)) {
michael@0 160 refreshTokenInfo();
michael@0 161 }
michael@0 162 *aTokFWVersion = ToNewUnicode(mTokenFWVersion);
michael@0 163 if (!*aTokFWVersion) return NS_ERROR_OUT_OF_MEMORY;
michael@0 164 return NS_OK;
michael@0 165 }
michael@0 166
michael@0 167 /* readonly attribute wstring tokenSerialNumber; */
michael@0 168 NS_IMETHODIMP nsPK11Token::GetTokenSerialNumber(char16_t **aTokSerialNum)
michael@0 169 {
michael@0 170 // handle removals/insertions
michael@0 171 if (mSeries != PK11_GetSlotSeries(mSlot)) {
michael@0 172 refreshTokenInfo();
michael@0 173 }
michael@0 174 *aTokSerialNum = ToNewUnicode(mTokenSerialNum);
michael@0 175 if (!*aTokSerialNum) return NS_ERROR_OUT_OF_MEMORY;
michael@0 176 return NS_OK;
michael@0 177 }
michael@0 178
michael@0 179 /* boolean isLoggedIn (); */
michael@0 180 NS_IMETHODIMP nsPK11Token::IsLoggedIn(bool *_retval)
michael@0 181 {
michael@0 182 nsNSSShutDownPreventionLock locker;
michael@0 183 if (isAlreadyShutDown())
michael@0 184 return NS_ERROR_NOT_AVAILABLE;
michael@0 185
michael@0 186 nsresult rv = NS_OK;
michael@0 187
michael@0 188 *_retval = PK11_IsLoggedIn(mSlot, 0);
michael@0 189
michael@0 190 return rv;
michael@0 191 }
michael@0 192
michael@0 193 /* void logout (in boolean force); */
michael@0 194 NS_IMETHODIMP
michael@0 195 nsPK11Token::Login(bool force)
michael@0 196 {
michael@0 197 nsNSSShutDownPreventionLock locker;
michael@0 198 if (isAlreadyShutDown())
michael@0 199 return NS_ERROR_NOT_AVAILABLE;
michael@0 200
michael@0 201 nsresult rv;
michael@0 202 SECStatus srv;
michael@0 203 bool test;
michael@0 204 rv = this->NeedsLogin(&test);
michael@0 205 if (NS_FAILED(rv)) return rv;
michael@0 206 if (test && force) {
michael@0 207 rv = this->LogoutSimple();
michael@0 208 if (NS_FAILED(rv)) return rv;
michael@0 209 }
michael@0 210 rv = setPassword(mSlot, mUIContext);
michael@0 211 if (NS_FAILED(rv)) return rv;
michael@0 212 srv = PK11_Authenticate(mSlot, true, mUIContext);
michael@0 213 return (srv == SECSuccess) ? NS_OK : NS_ERROR_FAILURE;
michael@0 214 }
michael@0 215
michael@0 216 NS_IMETHODIMP nsPK11Token::LogoutSimple()
michael@0 217 {
michael@0 218 nsNSSShutDownPreventionLock locker;
michael@0 219 if (isAlreadyShutDown())
michael@0 220 return NS_ERROR_NOT_AVAILABLE;
michael@0 221
michael@0 222 // PK11_MapError sets CKR_USER_NOT_LOGGED_IN to SEC_ERROR_LIBRARY_FAILURE,
michael@0 223 // so not going to learn anything here by a failure. Treat it like void.
michael@0 224 PK11_Logout(mSlot);
michael@0 225 return NS_OK;
michael@0 226 }
michael@0 227
michael@0 228 NS_IMETHODIMP nsPK11Token::LogoutAndDropAuthenticatedResources()
michael@0 229 {
michael@0 230 static NS_DEFINE_CID(kNSSComponentCID, NS_NSSCOMPONENT_CID);
michael@0 231
michael@0 232 nsresult rv = LogoutSimple();
michael@0 233
michael@0 234 if (NS_FAILED(rv))
michael@0 235 return rv;
michael@0 236
michael@0 237 nsCOMPtr<nsINSSComponent> nssComponent(do_GetService(kNSSComponentCID, &rv));
michael@0 238 if (NS_FAILED(rv))
michael@0 239 return rv;
michael@0 240
michael@0 241 return nssComponent->LogoutAuthenticatedPK11();
michael@0 242 }
michael@0 243
michael@0 244 /* void reset (); */
michael@0 245 NS_IMETHODIMP nsPK11Token::Reset()
michael@0 246 {
michael@0 247 nsNSSShutDownPreventionLock locker;
michael@0 248 if (isAlreadyShutDown())
michael@0 249 return NS_ERROR_NOT_AVAILABLE;
michael@0 250
michael@0 251 PK11_ResetToken(mSlot, 0);
michael@0 252 return NS_OK;
michael@0 253 }
michael@0 254
michael@0 255 /* readonly attribute long minimumPasswordLength; */
michael@0 256 NS_IMETHODIMP nsPK11Token::GetMinimumPasswordLength(int32_t *aMinimumPasswordLength)
michael@0 257 {
michael@0 258 nsNSSShutDownPreventionLock locker;
michael@0 259 if (isAlreadyShutDown())
michael@0 260 return NS_ERROR_NOT_AVAILABLE;
michael@0 261
michael@0 262 *aMinimumPasswordLength = PK11_GetMinimumPwdLength(mSlot);
michael@0 263
michael@0 264 return NS_OK;
michael@0 265 }
michael@0 266
michael@0 267 /* readonly attribute boolean needsUserInit; */
michael@0 268 NS_IMETHODIMP nsPK11Token::GetNeedsUserInit(bool *aNeedsUserInit)
michael@0 269 {
michael@0 270 nsNSSShutDownPreventionLock locker;
michael@0 271 if (isAlreadyShutDown())
michael@0 272 return NS_ERROR_NOT_AVAILABLE;
michael@0 273
michael@0 274 *aNeedsUserInit = PK11_NeedUserInit(mSlot);
michael@0 275 return NS_OK;
michael@0 276 }
michael@0 277
michael@0 278 /* boolean checkPassword (in wstring password); */
michael@0 279 NS_IMETHODIMP nsPK11Token::CheckPassword(const char16_t *password, bool *_retval)
michael@0 280 {
michael@0 281 nsNSSShutDownPreventionLock locker;
michael@0 282 if (isAlreadyShutDown())
michael@0 283 return NS_ERROR_NOT_AVAILABLE;
michael@0 284
michael@0 285 SECStatus srv;
michael@0 286 int32_t prerr;
michael@0 287 NS_ConvertUTF16toUTF8 aUtf8Password(password);
michael@0 288 srv = PK11_CheckUserPassword(mSlot,
michael@0 289 const_cast<char *>(aUtf8Password.get()));
michael@0 290 if (srv != SECSuccess) {
michael@0 291 *_retval = false;
michael@0 292 prerr = PR_GetError();
michael@0 293 if (prerr != SEC_ERROR_BAD_PASSWORD) {
michael@0 294 /* something really bad happened - throw an exception */
michael@0 295 return NS_ERROR_FAILURE;
michael@0 296 }
michael@0 297 } else {
michael@0 298 *_retval = true;
michael@0 299 }
michael@0 300 return NS_OK;
michael@0 301 }
michael@0 302
michael@0 303 /* void initPassword (in wstring initialPassword); */
michael@0 304 NS_IMETHODIMP nsPK11Token::InitPassword(const char16_t *initialPassword)
michael@0 305 {
michael@0 306 nsNSSShutDownPreventionLock locker;
michael@0 307 if (isAlreadyShutDown())
michael@0 308 return NS_ERROR_NOT_AVAILABLE;
michael@0 309
michael@0 310 nsresult rv = NS_OK;
michael@0 311 SECStatus status;
michael@0 312
michael@0 313 NS_ConvertUTF16toUTF8 aUtf8InitialPassword(initialPassword);
michael@0 314 status = PK11_InitPin(mSlot, "", const_cast<char*>(aUtf8InitialPassword.get()));
michael@0 315 if (status == SECFailure) { rv = NS_ERROR_FAILURE; goto done; }
michael@0 316
michael@0 317 done:
michael@0 318 return rv;
michael@0 319 }
michael@0 320
michael@0 321 /* long getAskPasswordTimes(); */
michael@0 322 NS_IMETHODIMP
michael@0 323 nsPK11Token::GetAskPasswordTimes(int32_t *rvAskTimes)
michael@0 324 {
michael@0 325 nsNSSShutDownPreventionLock locker;
michael@0 326 if (isAlreadyShutDown())
michael@0 327 return NS_ERROR_NOT_AVAILABLE;
michael@0 328
michael@0 329 int askTimes, askTimeout;
michael@0 330 PK11_GetSlotPWValues(mSlot, &askTimes, &askTimeout);
michael@0 331 *rvAskTimes = askTimes;
michael@0 332 return NS_OK;
michael@0 333 }
michael@0 334
michael@0 335 /* long getAskPasswordTimeout(); */
michael@0 336 NS_IMETHODIMP
michael@0 337 nsPK11Token::GetAskPasswordTimeout(int32_t *rvAskTimeout)
michael@0 338 {
michael@0 339 nsNSSShutDownPreventionLock locker;
michael@0 340 if (isAlreadyShutDown())
michael@0 341 return NS_ERROR_NOT_AVAILABLE;
michael@0 342
michael@0 343 int askTimes, askTimeout;
michael@0 344 PK11_GetSlotPWValues(mSlot, &askTimes, &askTimeout);
michael@0 345 *rvAskTimeout = askTimeout;
michael@0 346 return NS_OK;
michael@0 347 }
michael@0 348
michael@0 349 /* void setAskPasswordDefaults(in unsigned long askTimes,
michael@0 350 * in unsigned long timeout);
michael@0 351 */
michael@0 352 NS_IMETHODIMP
michael@0 353 nsPK11Token::SetAskPasswordDefaults(const int32_t askTimes,
michael@0 354 const int32_t askTimeout)
michael@0 355 {
michael@0 356 nsNSSShutDownPreventionLock locker;
michael@0 357 if (isAlreadyShutDown())
michael@0 358 return NS_ERROR_NOT_AVAILABLE;
michael@0 359
michael@0 360 PK11_SetSlotPWValues(mSlot, askTimes, askTimeout);
michael@0 361 return NS_OK;
michael@0 362 }
michael@0 363
michael@0 364 /* void changePassword (in wstring oldPassword, in wstring newPassword); */
michael@0 365 NS_IMETHODIMP nsPK11Token::ChangePassword(const char16_t *oldPassword, const char16_t *newPassword)
michael@0 366 {
michael@0 367 nsNSSShutDownPreventionLock locker;
michael@0 368 if (isAlreadyShutDown())
michael@0 369 return NS_ERROR_NOT_AVAILABLE;
michael@0 370
michael@0 371 SECStatus rv;
michael@0 372 NS_ConvertUTF16toUTF8 aUtf8OldPassword(oldPassword);
michael@0 373 NS_ConvertUTF16toUTF8 aUtf8NewPassword(newPassword);
michael@0 374
michael@0 375 rv = PK11_ChangePW(mSlot,
michael@0 376 (oldPassword ? const_cast<char *>(aUtf8OldPassword.get()) : nullptr),
michael@0 377 (newPassword ? const_cast<char *>(aUtf8NewPassword.get()) : nullptr));
michael@0 378 return (rv == SECSuccess) ? NS_OK : NS_ERROR_FAILURE;
michael@0 379 }
michael@0 380
michael@0 381 /* boolean isHardwareToken (); */
michael@0 382 NS_IMETHODIMP nsPK11Token::IsHardwareToken(bool *_retval)
michael@0 383 {
michael@0 384 nsNSSShutDownPreventionLock locker;
michael@0 385 if (isAlreadyShutDown())
michael@0 386 return NS_ERROR_NOT_AVAILABLE;
michael@0 387
michael@0 388 nsresult rv = NS_OK;
michael@0 389
michael@0 390 *_retval = PK11_IsHW(mSlot);
michael@0 391
michael@0 392 return rv;
michael@0 393 }
michael@0 394
michael@0 395 /* boolean needsLogin (); */
michael@0 396 NS_IMETHODIMP nsPK11Token::NeedsLogin(bool *_retval)
michael@0 397 {
michael@0 398 nsNSSShutDownPreventionLock locker;
michael@0 399 if (isAlreadyShutDown())
michael@0 400 return NS_ERROR_NOT_AVAILABLE;
michael@0 401
michael@0 402 nsresult rv = NS_OK;
michael@0 403
michael@0 404 *_retval = PK11_NeedLogin(mSlot);
michael@0 405
michael@0 406 return rv;
michael@0 407 }
michael@0 408
michael@0 409 /* boolean isFriendly (); */
michael@0 410 NS_IMETHODIMP nsPK11Token::IsFriendly(bool *_retval)
michael@0 411 {
michael@0 412 nsNSSShutDownPreventionLock locker;
michael@0 413 if (isAlreadyShutDown())
michael@0 414 return NS_ERROR_NOT_AVAILABLE;
michael@0 415
michael@0 416 nsresult rv = NS_OK;
michael@0 417
michael@0 418 *_retval = PK11_IsFriendly(mSlot);
michael@0 419
michael@0 420 return rv;
michael@0 421 }
michael@0 422
michael@0 423 /*=========================================================*/
michael@0 424
michael@0 425 NS_IMPL_ISUPPORTS(nsPK11TokenDB, nsIPK11TokenDB)
michael@0 426
michael@0 427 nsPK11TokenDB::nsPK11TokenDB()
michael@0 428 {
michael@0 429 /* member initializers and constructor code */
michael@0 430 }
michael@0 431
michael@0 432 nsPK11TokenDB::~nsPK11TokenDB()
michael@0 433 {
michael@0 434 /* destructor code */
michael@0 435 }
michael@0 436
michael@0 437 /* nsIPK11Token getInternalKeyToken (); */
michael@0 438 NS_IMETHODIMP nsPK11TokenDB::GetInternalKeyToken(nsIPK11Token **_retval)
michael@0 439 {
michael@0 440 nsNSSShutDownPreventionLock locker;
michael@0 441 nsresult rv = NS_OK;
michael@0 442 PK11SlotInfo *slot = 0;
michael@0 443 nsCOMPtr<nsIPK11Token> token;
michael@0 444
michael@0 445 slot = PK11_GetInternalKeySlot();
michael@0 446 if (!slot) { rv = NS_ERROR_FAILURE; goto done; }
michael@0 447
michael@0 448 token = new nsPK11Token(slot);
michael@0 449 *_retval = token;
michael@0 450 NS_ADDREF(*_retval);
michael@0 451
michael@0 452 done:
michael@0 453 if (slot) PK11_FreeSlot(slot);
michael@0 454 return rv;
michael@0 455 }
michael@0 456
michael@0 457 /* nsIPK11Token findTokenByName (in wchar tokenName); */
michael@0 458 NS_IMETHODIMP nsPK11TokenDB::
michael@0 459 FindTokenByName(const char16_t* tokenName, nsIPK11Token **_retval)
michael@0 460 {
michael@0 461 nsNSSShutDownPreventionLock locker;
michael@0 462 nsresult rv = NS_OK;
michael@0 463 PK11SlotInfo *slot = 0;
michael@0 464 NS_ConvertUTF16toUTF8 aUtf8TokenName(tokenName);
michael@0 465 slot = PK11_FindSlotByName(const_cast<char*>(aUtf8TokenName.get()));
michael@0 466 if (!slot) { rv = NS_ERROR_FAILURE; goto done; }
michael@0 467
michael@0 468 *_retval = new nsPK11Token(slot);
michael@0 469 NS_ADDREF(*_retval);
michael@0 470
michael@0 471 done:
michael@0 472 if (slot) PK11_FreeSlot(slot);
michael@0 473 return rv;
michael@0 474 }
michael@0 475
michael@0 476 /* nsIEnumerator listTokens (); */
michael@0 477 NS_IMETHODIMP nsPK11TokenDB::ListTokens(nsIEnumerator* *_retval)
michael@0 478 {
michael@0 479 nsNSSShutDownPreventionLock locker;
michael@0 480 nsCOMPtr<nsISupportsArray> array;
michael@0 481 PK11SlotList *list = 0;
michael@0 482 PK11SlotListElement *le;
michael@0 483
michael@0 484 *_retval = nullptr;
michael@0 485 nsresult rv = NS_NewISupportsArray(getter_AddRefs(array));
michael@0 486 if (NS_FAILED(rv)) { goto done; }
michael@0 487
michael@0 488 /* List all tokens, creating PK11Token objects and putting them
michael@0 489 * into the array.
michael@0 490 */
michael@0 491 list = PK11_GetAllTokens(CKM_INVALID_MECHANISM, false, false, 0);
michael@0 492 if (!list) { rv = NS_ERROR_FAILURE; goto done; }
michael@0 493
michael@0 494 for (le = PK11_GetFirstSafe(list); le; le = PK11_GetNextSafe(list, le, false)) {
michael@0 495 nsCOMPtr<nsIPK11Token> token = new nsPK11Token(le->slot);
michael@0 496 rv = array->AppendElement(token);
michael@0 497 if (NS_FAILED(rv)) {
michael@0 498 PK11_FreeSlotListElement(list, le);
michael@0 499 rv = NS_ERROR_OUT_OF_MEMORY;
michael@0 500 goto done;
michael@0 501 }
michael@0 502 }
michael@0 503
michael@0 504 rv = array->Enumerate(_retval);
michael@0 505
michael@0 506 done:
michael@0 507 if (list) PK11_FreeSlotList(list);
michael@0 508 return rv;
michael@0 509 }
michael@0 510

mercurial