Import from 1.9a8 tarball
[mozilla-nss.git] / security / nss / lib / ckfw / slot.c
blobafa09404abb2483bcf6faa34d7bc104e00606bc1
1 /* ***** BEGIN LICENSE BLOCK *****
2 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
4 * The contents of this file are subject to the Mozilla Public License Version
5 * 1.1 (the "License"); you may not use this file except in compliance with
6 * the License. You may obtain a copy of the License at
7 * http://www.mozilla.org/MPL/
9 * Software distributed under the License is distributed on an "AS IS" basis,
10 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
11 * for the specific language governing rights and limitations under the
12 * License.
14 * The Original Code is the Netscape security libraries.
16 * The Initial Developer of the Original Code is
17 * Netscape Communications Corporation.
18 * Portions created by the Initial Developer are Copyright (C) 1994-2000
19 * the Initial Developer. All Rights Reserved.
21 * Contributor(s):
23 * Alternatively, the contents of this file may be used under the terms of
24 * either the GNU General Public License Version 2 or later (the "GPL"), or
25 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
26 * in which case the provisions of the GPL or the LGPL are applicable instead
27 * of those above. If you wish to allow use of your version of this file only
28 * under the terms of either the GPL or the LGPL, and not to allow others to
29 * use your version of this file under the terms of the MPL, indicate your
30 * decision by deleting the provisions above and replace them with the notice
31 * and other provisions required by the GPL or the LGPL. If you do not delete
32 * the provisions above, a recipient may use your version of this file under
33 * the terms of any one of the MPL, the GPL or the LGPL.
35 * ***** END LICENSE BLOCK ***** */
37 #ifdef DEBUG
38 static const char CVS_ID[] = "@(#) $RCSfile: slot.c,v $ $Revision: 1.6 $ $Date: 2005/01/20 02:25:45 $";
39 #endif /* DEBUG */
42 * slot.c
44 * This file implements the NSSCKFWSlot type and methods.
47 #ifndef CK_T
48 #include "ck.h"
49 #endif /* CK_T */
52 * NSSCKFWSlot
54 * -- create/destroy --
55 * nssCKFWSlot_Create
56 * nssCKFWSlot_Destroy
58 * -- public accessors --
59 * NSSCKFWSlot_GetMDSlot
60 * NSSCKFWSlot_GetFWInstance
61 * NSSCKFWSlot_GetMDInstance
63 * -- implement public accessors --
64 * nssCKFWSlot_GetMDSlot
65 * nssCKFWSlot_GetFWInstance
66 * nssCKFWSlot_GetMDInstance
68 * -- private accessors --
69 * nssCKFWSlot_GetSlotID
70 * nssCKFWSlot_ClearToken
72 * -- module fronts --
73 * nssCKFWSlot_GetSlotDescription
74 * nssCKFWSlot_GetManufacturerID
75 * nssCKFWSlot_GetTokenPresent
76 * nssCKFWSlot_GetRemovableDevice
77 * nssCKFWSlot_GetHardwareSlot
78 * nssCKFWSlot_GetHardwareVersion
79 * nssCKFWSlot_GetFirmwareVersion
80 * nssCKFWSlot_InitToken
81 * nssCKFWSlot_GetToken
84 struct NSSCKFWSlotStr {
85 NSSCKFWMutex *mutex;
86 NSSCKMDSlot *mdSlot;
87 NSSCKFWInstance *fwInstance;
88 NSSCKMDInstance *mdInstance;
89 CK_SLOT_ID slotID;
92 * Everything above is set at creation time, and then not modified.
93 * The invariants the mutex protects are:
95 * 1) Each of the cached descriptions (versions, etc.) are in an
96 * internally consistant state.
98 * 2) The fwToken points to the token currently in the slot, and
99 * it is in a consistant state.
101 * Note that the calls accessing the cached descriptions will
102 * call the NSSCKMDSlot methods with the mutex locked. Those
103 * methods may then call the public NSSCKFWSlot routines. Those
104 * public routines only access the constant data above, so there's
105 * no problem. But be careful if you add to this object; mutexes
106 * are in general not reentrant, so don't create deadlock situations.
109 NSSUTF8 *slotDescription;
110 NSSUTF8 *manufacturerID;
111 CK_VERSION hardwareVersion;
112 CK_VERSION firmwareVersion;
113 NSSCKFWToken *fwToken;
116 #ifdef DEBUG
118 * But first, the pointer-tracking stuff.
120 * NOTE: the pointer-tracking support in NSS/base currently relies
121 * upon NSPR's CallOnce support. That, however, relies upon NSPR's
122 * locking, which is tied into the runtime. We need a pointer-tracker
123 * implementation that uses the locks supplied through C_Initialize.
124 * That support, however, can be filled in later. So for now, I'll
125 * just do this routines as no-ops.
128 static CK_RV
129 slot_add_pointer
131 const NSSCKFWSlot *fwSlot
134 return CKR_OK;
137 static CK_RV
138 slot_remove_pointer
140 const NSSCKFWSlot *fwSlot
143 return CKR_OK;
146 NSS_IMPLEMENT CK_RV
147 nssCKFWSlot_verifyPointer
149 const NSSCKFWSlot *fwSlot
152 return CKR_OK;
155 #endif /* DEBUG */
158 * nssCKFWSlot_Create
161 NSS_IMPLEMENT NSSCKFWSlot *
162 nssCKFWSlot_Create
164 NSSCKFWInstance *fwInstance,
165 NSSCKMDSlot *mdSlot,
166 CK_SLOT_ID slotID,
167 CK_RV *pError
170 NSSCKFWSlot *fwSlot;
171 NSSCKMDInstance *mdInstance;
172 NSSArena *arena;
174 #ifdef NSSDEBUG
175 if( (CK_RV *)NULL == pError ) {
176 return (NSSCKFWSlot *)NULL;
179 *pError = nssCKFWInstance_verifyPointer(fwInstance);
180 if( CKR_OK != *pError ) {
181 return (NSSCKFWSlot *)NULL;
183 #endif /* NSSDEBUG */
185 mdInstance = nssCKFWInstance_GetMDInstance(fwInstance);
186 if( (NSSCKMDInstance *)NULL == mdInstance ) {
187 *pError = CKR_GENERAL_ERROR;
188 return (NSSCKFWSlot *)NULL;
191 arena = nssCKFWInstance_GetArena(fwInstance, pError);
192 if( (NSSArena *)NULL == arena ) {
193 if( CKR_OK == *pError ) {
194 *pError = CKR_GENERAL_ERROR;
198 fwSlot = nss_ZNEW(arena, NSSCKFWSlot);
199 if( (NSSCKFWSlot *)NULL == fwSlot ) {
200 *pError = CKR_HOST_MEMORY;
201 return (NSSCKFWSlot *)NULL;
204 fwSlot->mdSlot = mdSlot;
205 fwSlot->fwInstance = fwInstance;
206 fwSlot->mdInstance = mdInstance;
207 fwSlot->slotID = slotID;
209 fwSlot->mutex = nssCKFWInstance_CreateMutex(fwInstance, arena, pError);
210 if( (NSSCKFWMutex *)NULL == fwSlot->mutex ) {
211 if( CKR_OK == *pError ) {
212 *pError = CKR_GENERAL_ERROR;
214 (void)nss_ZFreeIf(fwSlot);
215 return (NSSCKFWSlot *)NULL;
218 if( (void *)NULL != (void *)mdSlot->Initialize ) {
219 *pError = CKR_OK;
220 *pError = mdSlot->Initialize(mdSlot, fwSlot, mdInstance, fwInstance);
221 if( CKR_OK != *pError ) {
222 (void)nssCKFWMutex_Destroy(fwSlot->mutex);
223 (void)nss_ZFreeIf(fwSlot);
224 return (NSSCKFWSlot *)NULL;
228 #ifdef DEBUG
229 *pError = slot_add_pointer(fwSlot);
230 if( CKR_OK != *pError ) {
231 if( (void *)NULL != (void *)mdSlot->Destroy ) {
232 mdSlot->Destroy(mdSlot, fwSlot, mdInstance, fwInstance);
235 (void)nssCKFWMutex_Destroy(fwSlot->mutex);
236 (void)nss_ZFreeIf(fwSlot);
237 return (NSSCKFWSlot *)NULL;
239 #endif /* DEBUG */
241 return fwSlot;
245 * nssCKFWSlot_Destroy
248 NSS_IMPLEMENT CK_RV
249 nssCKFWSlot_Destroy
251 NSSCKFWSlot *fwSlot
254 CK_RV error = CKR_OK;
256 #ifdef NSSDEBUG
257 error = nssCKFWSlot_verifyPointer(fwSlot);
258 if( CKR_OK != error ) {
259 return error;
261 #endif /* NSSDEBUG */
262 if (fwSlot->fwToken) {
263 nssCKFWToken_Destroy(fwSlot->fwToken);
266 (void)nssCKFWMutex_Destroy(fwSlot->mutex);
268 if( (void *)NULL != (void *)fwSlot->mdSlot->Destroy ) {
269 fwSlot->mdSlot->Destroy(fwSlot->mdSlot, fwSlot,
270 fwSlot->mdInstance, fwSlot->fwInstance);
273 #ifdef DEBUG
274 error = slot_remove_pointer(fwSlot);
275 #endif /* DEBUG */
276 (void)nss_ZFreeIf(fwSlot);
277 return error;
281 * nssCKFWSlot_GetMDSlot
284 NSS_IMPLEMENT NSSCKMDSlot *
285 nssCKFWSlot_GetMDSlot
287 NSSCKFWSlot *fwSlot
290 #ifdef NSSDEBUG
291 if( CKR_OK != nssCKFWSlot_verifyPointer(fwSlot) ) {
292 return (NSSCKMDSlot *)NULL;
294 #endif /* NSSDEBUG */
296 return fwSlot->mdSlot;
300 * nssCKFWSlot_GetFWInstance
304 NSS_IMPLEMENT NSSCKFWInstance *
305 nssCKFWSlot_GetFWInstance
307 NSSCKFWSlot *fwSlot
310 #ifdef NSSDEBUG
311 if( CKR_OK != nssCKFWSlot_verifyPointer(fwSlot) ) {
312 return (NSSCKFWInstance *)NULL;
314 #endif /* NSSDEBUG */
316 return fwSlot->fwInstance;
320 * nssCKFWSlot_GetMDInstance
324 NSS_IMPLEMENT NSSCKMDInstance *
325 nssCKFWSlot_GetMDInstance
327 NSSCKFWSlot *fwSlot
330 #ifdef NSSDEBUG
331 if( CKR_OK != nssCKFWSlot_verifyPointer(fwSlot) ) {
332 return (NSSCKMDInstance *)NULL;
334 #endif /* NSSDEBUG */
336 return fwSlot->mdInstance;
340 * nssCKFWSlot_GetSlotID
343 NSS_IMPLEMENT CK_SLOT_ID
344 nssCKFWSlot_GetSlotID
346 NSSCKFWSlot *fwSlot
349 #ifdef NSSDEBUG
350 if( CKR_OK != nssCKFWSlot_verifyPointer(fwSlot) ) {
351 return (CK_SLOT_ID)0;
353 #endif /* NSSDEBUG */
355 return fwSlot->slotID;
359 * nssCKFWSlot_GetSlotDescription
362 NSS_IMPLEMENT CK_RV
363 nssCKFWSlot_GetSlotDescription
365 NSSCKFWSlot *fwSlot,
366 CK_CHAR slotDescription[64]
369 CK_RV error = CKR_OK;
371 #ifdef NSSDEBUG
372 if( (CK_CHAR_PTR)NULL == slotDescription ) {
373 return CKR_ARGUMENTS_BAD;
376 error = nssCKFWSlot_verifyPointer(fwSlot);
377 if( CKR_OK != error ) {
378 return error;
380 #endif /* NSSDEBUG */
382 error = nssCKFWMutex_Lock(fwSlot->mutex);
383 if( CKR_OK != error ) {
384 return error;
387 if( (NSSUTF8 *)NULL == fwSlot->slotDescription ) {
388 if( (void *)NULL != (void *)fwSlot->mdSlot->GetSlotDescription ) {
389 fwSlot->slotDescription = fwSlot->mdSlot->GetSlotDescription(
390 fwSlot->mdSlot, fwSlot, fwSlot->mdInstance,
391 fwSlot->fwInstance, &error);
392 if( ((NSSUTF8 *)NULL == fwSlot->slotDescription) && (CKR_OK != error) ) {
393 goto done;
395 } else {
396 fwSlot->slotDescription = (NSSUTF8 *) "";
400 (void)nssUTF8_CopyIntoFixedBuffer(fwSlot->slotDescription, (char *)slotDescription, 64, ' ');
401 error = CKR_OK;
403 done:
404 (void)nssCKFWMutex_Unlock(fwSlot->mutex);
405 return error;
409 * nssCKFWSlot_GetManufacturerID
412 NSS_IMPLEMENT CK_RV
413 nssCKFWSlot_GetManufacturerID
415 NSSCKFWSlot *fwSlot,
416 CK_CHAR manufacturerID[32]
419 CK_RV error = CKR_OK;
421 #ifdef NSSDEBUG
422 if( (CK_CHAR_PTR)NULL == manufacturerID ) {
423 return CKR_ARGUMENTS_BAD;
426 error = nssCKFWSlot_verifyPointer(fwSlot);
427 if( CKR_OK != error ) {
428 return error;
430 #endif /* NSSDEBUG */
432 error = nssCKFWMutex_Lock(fwSlot->mutex);
433 if( CKR_OK != error ) {
434 return error;
437 if( (NSSUTF8 *)NULL == fwSlot->manufacturerID ) {
438 if( (void *)NULL != (void *)fwSlot->mdSlot->GetManufacturerID ) {
439 fwSlot->manufacturerID = fwSlot->mdSlot->GetManufacturerID(
440 fwSlot->mdSlot, fwSlot, fwSlot->mdInstance,
441 fwSlot->fwInstance, &error);
442 if( ((NSSUTF8 *)NULL == fwSlot->manufacturerID) && (CKR_OK != error) ) {
443 goto done;
445 } else {
446 fwSlot->manufacturerID = (NSSUTF8 *) "";
450 (void)nssUTF8_CopyIntoFixedBuffer(fwSlot->manufacturerID, (char *)manufacturerID, 32, ' ');
451 error = CKR_OK;
453 done:
454 (void)nssCKFWMutex_Unlock(fwSlot->mutex);
455 return error;
459 * nssCKFWSlot_GetTokenPresent
462 NSS_IMPLEMENT CK_BBOOL
463 nssCKFWSlot_GetTokenPresent
465 NSSCKFWSlot *fwSlot
468 #ifdef NSSDEBUG
469 if( CKR_OK != nssCKFWSlot_verifyPointer(fwSlot) ) {
470 return CK_FALSE;
472 #endif /* NSSDEBUG */
474 if( (void *)NULL == (void *)fwSlot->mdSlot->GetTokenPresent ) {
475 return CK_TRUE;
478 return fwSlot->mdSlot->GetTokenPresent(fwSlot->mdSlot, fwSlot,
479 fwSlot->mdInstance, fwSlot->fwInstance);
483 * nssCKFWSlot_GetRemovableDevice
486 NSS_IMPLEMENT CK_BBOOL
487 nssCKFWSlot_GetRemovableDevice
489 NSSCKFWSlot *fwSlot
492 #ifdef NSSDEBUG
493 if( CKR_OK != nssCKFWSlot_verifyPointer(fwSlot) ) {
494 return CK_FALSE;
496 #endif /* NSSDEBUG */
498 if( (void *)NULL == (void *)fwSlot->mdSlot->GetRemovableDevice ) {
499 return CK_FALSE;
502 return fwSlot->mdSlot->GetRemovableDevice(fwSlot->mdSlot, fwSlot,
503 fwSlot->mdInstance, fwSlot->fwInstance);
507 * nssCKFWSlot_GetHardwareSlot
510 NSS_IMPLEMENT CK_BBOOL
511 nssCKFWSlot_GetHardwareSlot
513 NSSCKFWSlot *fwSlot
516 #ifdef NSSDEBUG
517 if( CKR_OK != nssCKFWSlot_verifyPointer(fwSlot) ) {
518 return CK_FALSE;
520 #endif /* NSSDEBUG */
522 if( (void *)NULL == (void *)fwSlot->mdSlot->GetHardwareSlot ) {
523 return CK_FALSE;
526 return fwSlot->mdSlot->GetHardwareSlot(fwSlot->mdSlot, fwSlot,
527 fwSlot->mdInstance, fwSlot->fwInstance);
531 * nssCKFWSlot_GetHardwareVersion
534 NSS_IMPLEMENT CK_VERSION
535 nssCKFWSlot_GetHardwareVersion
537 NSSCKFWSlot *fwSlot
540 CK_VERSION rv;
542 #ifdef NSSDEBUG
543 if( CKR_OK != nssCKFWSlot_verifyPointer(fwSlot) ) {
544 rv.major = rv.minor = 0;
545 return rv;
547 #endif /* NSSDEBUG */
549 if( CKR_OK != nssCKFWMutex_Lock(fwSlot->mutex) ) {
550 rv.major = rv.minor = 0;
551 return rv;
554 if( (0 != fwSlot->hardwareVersion.major) ||
555 (0 != fwSlot->hardwareVersion.minor) ) {
556 rv = fwSlot->hardwareVersion;
557 goto done;
560 if( (void *)NULL != (void *)fwSlot->mdSlot->GetHardwareVersion ) {
561 fwSlot->hardwareVersion = fwSlot->mdSlot->GetHardwareVersion(
562 fwSlot->mdSlot, fwSlot, fwSlot->mdInstance, fwSlot->fwInstance);
563 } else {
564 fwSlot->hardwareVersion.major = 0;
565 fwSlot->hardwareVersion.minor = 1;
568 rv = fwSlot->hardwareVersion;
569 done:
570 (void)nssCKFWMutex_Unlock(fwSlot->mutex);
571 return rv;
575 * nssCKFWSlot_GetFirmwareVersion
578 NSS_IMPLEMENT CK_VERSION
579 nssCKFWSlot_GetFirmwareVersion
581 NSSCKFWSlot *fwSlot
584 CK_VERSION rv;
586 #ifdef NSSDEBUG
587 if( CKR_OK != nssCKFWSlot_verifyPointer(fwSlot) ) {
588 rv.major = rv.minor = 0;
589 return rv;
591 #endif /* NSSDEBUG */
593 if( CKR_OK != nssCKFWMutex_Lock(fwSlot->mutex) ) {
594 rv.major = rv.minor = 0;
595 return rv;
598 if( (0 != fwSlot->firmwareVersion.major) ||
599 (0 != fwSlot->firmwareVersion.minor) ) {
600 rv = fwSlot->firmwareVersion;
601 goto done;
604 if( (void *)NULL != (void *)fwSlot->mdSlot->GetFirmwareVersion ) {
605 fwSlot->firmwareVersion = fwSlot->mdSlot->GetFirmwareVersion(
606 fwSlot->mdSlot, fwSlot, fwSlot->mdInstance, fwSlot->fwInstance);
607 } else {
608 fwSlot->firmwareVersion.major = 0;
609 fwSlot->firmwareVersion.minor = 1;
612 rv = fwSlot->firmwareVersion;
613 done:
614 (void)nssCKFWMutex_Unlock(fwSlot->mutex);
615 return rv;
619 * nssCKFWSlot_GetToken
622 NSS_IMPLEMENT NSSCKFWToken *
623 nssCKFWSlot_GetToken
625 NSSCKFWSlot *fwSlot,
626 CK_RV *pError
629 NSSCKMDToken *mdToken;
630 NSSCKFWToken *fwToken;
632 #ifdef NSSDEBUG
633 if( (CK_RV *)NULL == pError ) {
634 return (NSSCKFWToken *)NULL;
637 *pError = nssCKFWSlot_verifyPointer(fwSlot);
638 if( CKR_OK != *pError ) {
639 return (NSSCKFWToken *)NULL;
641 #endif /* NSSDEBUG */
643 *pError = nssCKFWMutex_Lock(fwSlot->mutex);
644 if( CKR_OK != *pError ) {
645 return (NSSCKFWToken *)NULL;
648 if( (NSSCKFWToken *)NULL == fwSlot->fwToken ) {
649 if( (void *)NULL == (void *)fwSlot->mdSlot->GetToken ) {
650 *pError = CKR_GENERAL_ERROR;
651 fwToken = (NSSCKFWToken *)NULL;
652 goto done;
655 mdToken = fwSlot->mdSlot->GetToken(fwSlot->mdSlot, fwSlot,
656 fwSlot->mdInstance, fwSlot->fwInstance, pError);
657 if( (NSSCKMDToken *)NULL == mdToken ) {
658 if( CKR_OK == *pError ) {
659 *pError = CKR_GENERAL_ERROR;
661 return (NSSCKFWToken *)NULL;
664 fwToken = nssCKFWToken_Create(fwSlot, mdToken, pError);
665 fwSlot->fwToken = fwToken;
666 } else {
667 fwToken = fwSlot->fwToken;
670 done:
671 (void)nssCKFWMutex_Unlock(fwSlot->mutex);
672 return fwToken;
676 * nssCKFWSlot_ClearToken
679 NSS_IMPLEMENT void
680 nssCKFWSlot_ClearToken
682 NSSCKFWSlot *fwSlot
685 #ifdef NSSDEBUG
686 if( CKR_OK != nssCKFWSlot_verifyPointer(fwSlot) ) {
687 return;
689 #endif /* NSSDEBUG */
691 if( CKR_OK != nssCKFWMutex_Lock(fwSlot->mutex) ) {
692 /* Now what? */
693 return;
696 fwSlot->fwToken = (NSSCKFWToken *)NULL;
697 (void)nssCKFWMutex_Unlock(fwSlot->mutex);
698 return;
702 * NSSCKFWSlot_GetMDSlot
706 NSS_IMPLEMENT NSSCKMDSlot *
707 NSSCKFWSlot_GetMDSlot
709 NSSCKFWSlot *fwSlot
712 #ifdef DEBUG
713 if( CKR_OK != nssCKFWSlot_verifyPointer(fwSlot) ) {
714 return (NSSCKMDSlot *)NULL;
716 #endif /* DEBUG */
718 return nssCKFWSlot_GetMDSlot(fwSlot);
722 * NSSCKFWSlot_GetFWInstance
726 NSS_IMPLEMENT NSSCKFWInstance *
727 NSSCKFWSlot_GetFWInstance
729 NSSCKFWSlot *fwSlot
732 #ifdef DEBUG
733 if( CKR_OK != nssCKFWSlot_verifyPointer(fwSlot) ) {
734 return (NSSCKFWInstance *)NULL;
736 #endif /* DEBUG */
738 return nssCKFWSlot_GetFWInstance(fwSlot);
742 * NSSCKFWSlot_GetMDInstance
746 NSS_IMPLEMENT NSSCKMDInstance *
747 NSSCKFWSlot_GetMDInstance
749 NSSCKFWSlot *fwSlot
752 #ifdef DEBUG
753 if( CKR_OK != nssCKFWSlot_verifyPointer(fwSlot) ) {
754 return (NSSCKMDInstance *)NULL;
756 #endif /* DEBUG */
758 return nssCKFWSlot_GetMDInstance(fwSlot);