Bug 1914685 - [wpt-sync] Update web-platform-tests to 26c88095d89792c886494e30c85aca3...
[gecko.git] / security / nss / lib / pk11wrap / dev3hack.c
blob2d41a34d852826d768e266f531d0bf96bab41956
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/. */
5 #ifndef PKIT_H
6 #include "pkit.h"
7 #endif /* PKIT_H */
9 #ifndef DEVM_H
10 #include "devm.h"
11 #endif /* DEVM_H */
13 #include "pki3hack.h"
14 #include "dev3hack.h"
15 #include "pkim.h"
17 #ifndef BASE_H
18 #include "base.h"
19 #endif /* BASE_H */
21 #include "pk11func.h"
22 #include "secmodti.h"
23 #include "secerr.h"
25 NSS_IMPLEMENT nssSession *
26 nssSession_ImportNSS3Session(NSSArena *arenaOpt,
27 CK_SESSION_HANDLE session,
28 PZLock *lock, PRBool rw)
30 nssSession *rvSession = NULL;
31 if (session != CK_INVALID_HANDLE) {
32 rvSession = nss_ZNEW(arenaOpt, nssSession);
33 if (rvSession) {
34 rvSession->handle = session;
35 rvSession->lock = lock;
36 rvSession->ownLock = PR_FALSE;
37 rvSession->isRW = rw;
40 return rvSession;
43 NSS_IMPLEMENT nssSession *
44 nssSlot_CreateSession(
45 NSSSlot *slot,
46 NSSArena *arenaOpt,
47 PRBool readWrite)
49 nssSession *rvSession;
51 if (!readWrite) {
52 /* nss3hack version only returns rw swssions */
53 return NULL;
55 rvSession = nss_ZNEW(arenaOpt, nssSession);
56 if (!rvSession) {
57 return (nssSession *)NULL;
60 rvSession->handle = PK11_GetRWSession(slot->pk11slot);
61 if (rvSession->handle == CK_INVALID_HANDLE) {
62 nss_ZFreeIf(rvSession);
63 return NULL;
65 rvSession->isRW = PR_TRUE;
66 rvSession->slot = slot;
68 * The session doesn't need its own lock. Here's why.
69 * 1. If we are reusing the default RW session of the slot,
70 * the slot lock is already locked to protect the session.
71 * 2. If the module is not thread safe, the slot (or rather
72 * module) lock is already locked.
73 * 3. If the module is thread safe and we are using a new
74 * session, no higher-level lock has been locked and we
75 * would need a lock for the new session. However, the
76 * current usage of the session is that it is always
77 * used and destroyed within the same function and never
78 * shared with another thread.
79 * So the session is either already protected by another
80 * lock or only used by one thread.
82 rvSession->lock = NULL;
83 rvSession->ownLock = PR_FALSE;
84 return rvSession;
87 NSS_IMPLEMENT PRStatus
88 nssSession_Destroy(nssSession *s)
90 PRStatus rv = PR_SUCCESS;
91 if (s) {
92 if (s->isRW) {
93 PK11_RestoreROSession(s->slot->pk11slot, s->handle);
95 rv = nss_ZFreeIf(s);
97 return rv;
100 static NSSSlot *
101 nssSlot_CreateFromPK11SlotInfo(NSSTrustDomain *td, PK11SlotInfo *nss3slot)
103 NSSSlot *rvSlot;
104 NSSArena *arena;
105 arena = nssArena_Create();
106 if (!arena) {
107 return NULL;
109 rvSlot = nss_ZNEW(arena, NSSSlot);
110 if (!rvSlot) {
111 nssArena_Destroy(arena);
112 return NULL;
114 rvSlot->base.refCount = 1;
115 rvSlot->base.lock = PZ_NewLock(nssILockOther);
116 rvSlot->base.arena = arena;
117 rvSlot->pk11slot = PK11_ReferenceSlot(nss3slot);
118 rvSlot->epv = nss3slot->functionList;
119 rvSlot->slotID = nss3slot->slotID;
120 /* Grab the slot name from the PKCS#11 fixed-length buffer */
121 rvSlot->base.name = nssUTF8_Duplicate(nss3slot->slot_name, td->arena);
122 rvSlot->lock = (nss3slot->isThreadSafe) ? NULL : nss3slot->sessionLock;
123 rvSlot->isPresentLock = PZ_NewLock(nssiLockOther);
124 rvSlot->isPresentCondition = PR_NewCondVar(rvSlot->isPresentLock);
125 rvSlot->isPresentThread = NULL;
126 rvSlot->lastTokenPingState = nssSlotLastPingState_Reset;
127 return rvSlot;
130 NSSToken *
131 nssToken_CreateFromPK11SlotInfo(NSSTrustDomain *td, PK11SlotInfo *nss3slot)
133 NSSToken *rvToken;
134 NSSArena *arena;
136 /* Don't create a token object for a disabled slot */
137 if (nss3slot->disabled) {
138 PORT_SetError(SEC_ERROR_NO_TOKEN);
139 return NULL;
141 arena = nssArena_Create();
142 if (!arena) {
143 return NULL;
145 rvToken = nss_ZNEW(arena, NSSToken);
146 if (!rvToken) {
147 nssArena_Destroy(arena);
148 return NULL;
150 rvToken->base.refCount = 1;
151 rvToken->base.lock = PZ_NewLock(nssILockOther);
152 if (!rvToken->base.lock) {
153 nssArena_Destroy(arena);
154 return NULL;
156 rvToken->base.arena = arena;
157 rvToken->pk11slot = PK11_ReferenceSlot(nss3slot);
158 rvToken->epv = nss3slot->functionList;
159 rvToken->defaultSession = nssSession_ImportNSS3Session(td->arena,
160 nss3slot->session,
161 nss3slot->sessionLock,
162 nss3slot->defRWSession);
163 #if 0 /* we should do this instead of blindly continuing. */
164 if (!rvToken->defaultSession) {
165 PORT_SetError(SEC_ERROR_NO_TOKEN);
166 goto loser;
168 #endif
169 if (!PK11_IsInternal(nss3slot) && PK11_IsHW(nss3slot)) {
170 rvToken->cache = nssTokenObjectCache_Create(rvToken,
171 PR_TRUE, PR_TRUE, PR_TRUE);
172 if (!rvToken->cache)
173 goto loser;
175 rvToken->trustDomain = td;
176 /* Grab the token name from the PKCS#11 fixed-length buffer */
177 rvToken->base.name = nssUTF8_Duplicate(nss3slot->token_name, td->arena);
178 rvToken->slot = nssSlot_CreateFromPK11SlotInfo(td, nss3slot);
179 if (!rvToken->slot) {
180 goto loser;
182 if (rvToken->defaultSession)
183 rvToken->defaultSession->slot = rvToken->slot;
184 return rvToken;
185 loser:
186 PZ_DestroyLock(rvToken->base.lock);
187 nssArena_Destroy(arena);
188 return NULL;
191 NSS_IMPLEMENT void
192 nssToken_UpdateName(NSSToken *token)
194 if (!token) {
195 return;
197 token->base.name = nssUTF8_Duplicate(token->pk11slot->token_name, token->base.arena);
200 NSS_IMPLEMENT PRBool
201 nssSlot_IsPermanent(NSSSlot *slot)
203 return slot->pk11slot->isPerm;
206 NSS_IMPLEMENT PRBool
207 nssSlot_IsFriendly(NSSSlot *slot)
209 return PK11_IsFriendly(slot->pk11slot);
212 NSS_IMPLEMENT PRStatus
213 nssToken_Refresh(NSSToken *token)
215 PK11SlotInfo *nss3slot;
217 if (!token) {
218 return PR_SUCCESS;
220 nss3slot = token->pk11slot;
221 token->defaultSession =
222 nssSession_ImportNSS3Session(token->slot->base.arena,
223 nss3slot->session,
224 nss3slot->sessionLock,
225 nss3slot->defRWSession);
226 return token->defaultSession ? PR_SUCCESS : PR_FAILURE;
229 NSS_IMPLEMENT PRStatus
230 nssToken_GetTrustOrder(NSSToken *tok)
232 PK11SlotInfo *slot;
233 SECMODModule *module;
234 slot = tok->pk11slot;
235 module = PK11_GetModule(slot);
236 return module->trustOrder;
239 NSS_IMPLEMENT PRBool
240 nssSlot_IsLoggedIn(NSSSlot *slot)
242 if (!slot->pk11slot->needLogin) {
243 return PR_TRUE;
245 return PK11_IsLoggedIn(slot->pk11slot, NULL);
248 NSSTrustDomain *
249 nssToken_GetTrustDomain(NSSToken *token)
251 return token->trustDomain;
254 NSS_EXTERN PRStatus
255 nssTrustDomain_RemoveTokenCertsFromCache(
256 NSSTrustDomain *td,
257 NSSToken *token);
259 NSS_IMPLEMENT PRStatus
260 nssToken_NotifyCertsNotVisible(
261 NSSToken *tok)
263 return nssTrustDomain_RemoveTokenCertsFromCache(tok->trustDomain, tok);