Mercurial > trustbridge > nss-cmake-static
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 |