comparison nss/lib/dev/devslot.c @ 0:1e5118fa0cb1

This is NSS with a Cmake Buildsyste To compile a static NSS library for Windows we've used the Chromium-NSS fork and added a Cmake buildsystem to compile it statically for Windows. See README.chromium for chromium changes and README.trustbridge for our modifications.
author Andre Heinecke <andre.heinecke@intevation.de>
date Mon, 28 Jul 2014 10:47:06 +0200
parents
children
comparison
equal deleted inserted replaced
-1:000000000000 0:1e5118fa0cb1
1 /* This Source Code Form is subject to the terms of the Mozilla Public
2 * License, v. 2.0. If a copy of the MPL was not distributed with this
3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
4
5 #include "pkcs11.h"
6
7 #ifndef DEVM_H
8 #include "devm.h"
9 #endif /* DEVM_H */
10
11 #ifndef CKHELPER_H
12 #include "ckhelper.h"
13 #endif /* CKHELPER_H */
14
15 #include "pk11pub.h"
16
17 /* measured in seconds */
18 #define NSSSLOT_TOKEN_DELAY_TIME 1
19
20 /* this should track global and per-transaction login information */
21
22 #define NSSSLOT_IS_FRIENDLY(slot) \
23 (slot->base.flags & NSSSLOT_FLAGS_FRIENDLY)
24
25 /* measured as interval */
26 static PRIntervalTime s_token_delay_time = 0;
27
28 /* The flags needed to open a read-only session. */
29 static const CK_FLAGS s_ck_readonly_flags = CKF_SERIAL_SESSION;
30
31 NSS_IMPLEMENT PRStatus
32 nssSlot_Destroy (
33 NSSSlot *slot
34 )
35 {
36 if (slot) {
37 if (PR_ATOMIC_DECREMENT(&slot->base.refCount) == 0) {
38 PZ_DestroyLock(slot->base.lock);
39 return nssArena_Destroy(slot->base.arena);
40 }
41 }
42 return PR_SUCCESS;
43 }
44
45 void
46 nssSlot_EnterMonitor(NSSSlot *slot)
47 {
48 if (slot->lock) {
49 PZ_Lock(slot->lock);
50 }
51 }
52
53 void
54 nssSlot_ExitMonitor(NSSSlot *slot)
55 {
56 if (slot->lock) {
57 PZ_Unlock(slot->lock);
58 }
59 }
60
61 NSS_IMPLEMENT void
62 NSSSlot_Destroy (
63 NSSSlot *slot
64 )
65 {
66 (void)nssSlot_Destroy(slot);
67 }
68
69 NSS_IMPLEMENT NSSSlot *
70 nssSlot_AddRef (
71 NSSSlot *slot
72 )
73 {
74 PR_ATOMIC_INCREMENT(&slot->base.refCount);
75 return slot;
76 }
77
78 NSS_IMPLEMENT NSSUTF8 *
79 nssSlot_GetName (
80 NSSSlot *slot
81 )
82 {
83 return slot->base.name;
84 }
85
86 NSS_IMPLEMENT NSSUTF8 *
87 nssSlot_GetTokenName (
88 NSSSlot *slot
89 )
90 {
91 return nssToken_GetName(slot->token);
92 }
93
94 NSS_IMPLEMENT void
95 nssSlot_ResetDelay (
96 NSSSlot *slot
97 )
98 {
99 slot->lastTokenPing = 0;
100 }
101
102 static PRBool
103 within_token_delay_period(NSSSlot *slot)
104 {
105 PRIntervalTime time, lastTime;
106 /* Set the delay time for checking the token presence */
107 if (s_token_delay_time == 0) {
108 s_token_delay_time = PR_SecondsToInterval(NSSSLOT_TOKEN_DELAY_TIME);
109 }
110 time = PR_IntervalNow();
111 lastTime = slot->lastTokenPing;
112 if ((lastTime) && ((time - lastTime) < s_token_delay_time)) {
113 return PR_TRUE;
114 }
115 slot->lastTokenPing = time;
116 return PR_FALSE;
117 }
118
119 NSS_IMPLEMENT PRBool
120 nssSlot_IsTokenPresent (
121 NSSSlot *slot
122 )
123 {
124 CK_RV ckrv;
125 PRStatus nssrv;
126 /* XXX */
127 nssSession *session;
128 CK_SLOT_INFO slotInfo;
129 void *epv;
130 /* permanent slots are always present unless they're disabled */
131 if (nssSlot_IsPermanent(slot)) {
132 return !PK11_IsDisabled(slot->pk11slot);
133 }
134 /* avoid repeated calls to check token status within set interval */
135 if (within_token_delay_period(slot)) {
136 return ((slot->ckFlags & CKF_TOKEN_PRESENT) != 0);
137 }
138
139 /* First obtain the slot info */
140 epv = slot->epv;
141 if (!epv) {
142 return PR_FALSE;
143 }
144 nssSlot_EnterMonitor(slot);
145 ckrv = CKAPI(epv)->C_GetSlotInfo(slot->slotID, &slotInfo);
146 nssSlot_ExitMonitor(slot);
147 if (ckrv != CKR_OK) {
148 slot->token->base.name[0] = 0; /* XXX */
149 return PR_FALSE;
150 }
151 slot->ckFlags = slotInfo.flags;
152 /* check for the presence of the token */
153 if ((slot->ckFlags & CKF_TOKEN_PRESENT) == 0) {
154 if (!slot->token) {
155 /* token was never present */
156 return PR_FALSE;
157 }
158 session = nssToken_GetDefaultSession(slot->token);
159 if (session) {
160 nssSession_EnterMonitor(session);
161 /* token is not present */
162 if (session->handle != CK_INVALID_SESSION) {
163 /* session is valid, close and invalidate it */
164 CKAPI(epv)->C_CloseSession(session->handle);
165 session->handle = CK_INVALID_SESSION;
166 }
167 nssSession_ExitMonitor(session);
168 }
169 if (slot->token->base.name[0] != 0) {
170 /* notify the high-level cache that the token is removed */
171 slot->token->base.name[0] = 0; /* XXX */
172 nssToken_NotifyCertsNotVisible(slot->token);
173 }
174 slot->token->base.name[0] = 0; /* XXX */
175 /* clear the token cache */
176 nssToken_Remove(slot->token);
177 return PR_FALSE;
178 }
179 /* token is present, use the session info to determine if the card
180 * has been removed and reinserted.
181 */
182 session = nssToken_GetDefaultSession(slot->token);
183 if (session) {
184 PRBool isPresent = PR_FALSE;
185 nssSession_EnterMonitor(session);
186 if (session->handle != CK_INVALID_SESSION) {
187 CK_SESSION_INFO sessionInfo;
188 ckrv = CKAPI(epv)->C_GetSessionInfo(session->handle, &sessionInfo);
189 if (ckrv != CKR_OK) {
190 /* session is screwy, close and invalidate it */
191 CKAPI(epv)->C_CloseSession(session->handle);
192 session->handle = CK_INVALID_SESSION;
193 }
194 }
195 isPresent = session->handle != CK_INVALID_SESSION;
196 nssSession_ExitMonitor(session);
197 /* token not removed, finished */
198 if (isPresent)
199 return PR_TRUE;
200 }
201 /* the token has been removed, and reinserted, or the slot contains
202 * a token it doesn't recognize. invalidate all the old
203 * information we had on this token, if we can't refresh, clear
204 * the present flag */
205 nssToken_NotifyCertsNotVisible(slot->token);
206 nssToken_Remove(slot->token);
207 /* token has been removed, need to refresh with new session */
208 nssrv = nssSlot_Refresh(slot);
209 if (nssrv != PR_SUCCESS) {
210 slot->token->base.name[0] = 0; /* XXX */
211 slot->ckFlags &= ~CKF_TOKEN_PRESENT;
212 return PR_FALSE;
213 }
214 return PR_TRUE;
215 }
216
217 NSS_IMPLEMENT void *
218 nssSlot_GetCryptokiEPV (
219 NSSSlot *slot
220 )
221 {
222 return slot->epv;
223 }
224
225 NSS_IMPLEMENT NSSToken *
226 nssSlot_GetToken (
227 NSSSlot *slot
228 )
229 {
230 if (nssSlot_IsTokenPresent(slot)) {
231 return nssToken_AddRef(slot->token);
232 }
233 return (NSSToken *)NULL;
234 }
235
236 NSS_IMPLEMENT PRStatus
237 nssSession_EnterMonitor (
238 nssSession *s
239 )
240 {
241 if (s->lock) PZ_Lock(s->lock);
242 return PR_SUCCESS;
243 }
244
245 NSS_IMPLEMENT PRStatus
246 nssSession_ExitMonitor (
247 nssSession *s
248 )
249 {
250 return (s->lock) ? PZ_Unlock(s->lock) : PR_SUCCESS;
251 }
252
253 NSS_EXTERN PRBool
254 nssSession_IsReadWrite (
255 nssSession *s
256 )
257 {
258 return s->isRW;
259 }
260
This site is hosted by Intevation GmbH (Datenschutzerklärung und Impressum | Privacy Policy and Imprint)