1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/security/nss/lib/pk11wrap/dev3hack.c Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,305 @@ 1.4 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.5 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.6 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.7 + 1.8 +#ifndef PKIT_H 1.9 +#include "pkit.h" 1.10 +#endif /* PKIT_H */ 1.11 + 1.12 +#ifndef DEVM_H 1.13 +#include "devm.h" 1.14 +#endif /* DEVM_H */ 1.15 + 1.16 +#include "pki3hack.h" 1.17 +#include "dev3hack.h" 1.18 +#include "pkim.h" 1.19 + 1.20 +#ifndef BASE_H 1.21 +#include "base.h" 1.22 +#endif /* BASE_H */ 1.23 + 1.24 +#include "pk11func.h" 1.25 +#include "secmodti.h" 1.26 +#include "secerr.h" 1.27 + 1.28 +NSS_IMPLEMENT nssSession * 1.29 +nssSession_ImportNSS3Session(NSSArena *arenaOpt, 1.30 + CK_SESSION_HANDLE session, 1.31 + PZLock *lock, PRBool rw) 1.32 +{ 1.33 + nssSession *rvSession = NULL; 1.34 + if (session != CK_INVALID_SESSION) { 1.35 + rvSession = nss_ZNEW(arenaOpt, nssSession); 1.36 + if (rvSession) { 1.37 + rvSession->handle = session; 1.38 + rvSession->lock = lock; 1.39 + rvSession->ownLock = PR_FALSE; 1.40 + rvSession->isRW = rw; 1.41 + } 1.42 + } 1.43 + return rvSession; 1.44 +} 1.45 + 1.46 +NSS_IMPLEMENT nssSession * 1.47 +nssSlot_CreateSession 1.48 +( 1.49 + NSSSlot *slot, 1.50 + NSSArena *arenaOpt, 1.51 + PRBool readWrite 1.52 +) 1.53 +{ 1.54 + nssSession *rvSession; 1.55 + 1.56 + if (!readWrite) { 1.57 + /* nss3hack version only returns rw swssions */ 1.58 + return NULL; 1.59 + } 1.60 + rvSession = nss_ZNEW(arenaOpt, nssSession); 1.61 + if (!rvSession) { 1.62 + return (nssSession *)NULL; 1.63 + } 1.64 + 1.65 + rvSession->handle = PK11_GetRWSession(slot->pk11slot); 1.66 + if (rvSession->handle == CK_INVALID_HANDLE) { 1.67 + nss_ZFreeIf(rvSession); 1.68 + return NULL; 1.69 + } 1.70 + rvSession->isRW = PR_TRUE; 1.71 + rvSession->slot = slot; 1.72 + /* 1.73 + * The session doesn't need its own lock. Here's why. 1.74 + * 1. If we are reusing the default RW session of the slot, 1.75 + * the slot lock is already locked to protect the session. 1.76 + * 2. If the module is not thread safe, the slot (or rather 1.77 + * module) lock is already locked. 1.78 + * 3. If the module is thread safe and we are using a new 1.79 + * session, no higher-level lock has been locked and we 1.80 + * would need a lock for the new session. However, the 1.81 + * current usage of the session is that it is always 1.82 + * used and destroyed within the same function and never 1.83 + * shared with another thread. 1.84 + * So the session is either already protected by another 1.85 + * lock or only used by one thread. 1.86 + */ 1.87 + rvSession->lock = NULL; 1.88 + rvSession->ownLock = PR_FALSE; 1.89 + return rvSession; 1.90 +} 1.91 + 1.92 +NSS_IMPLEMENT PRStatus 1.93 +nssSession_Destroy 1.94 +( 1.95 + nssSession *s 1.96 +) 1.97 +{ 1.98 + CK_RV ckrv = CKR_OK; 1.99 + if (s) { 1.100 + if (s->isRW) { 1.101 + PK11_RestoreROSession(s->slot->pk11slot, s->handle); 1.102 + } 1.103 + nss_ZFreeIf(s); 1.104 + } 1.105 + return (ckrv == CKR_OK) ? PR_SUCCESS : PR_FAILURE; 1.106 +} 1.107 + 1.108 +static NSSSlot * 1.109 +nssSlot_CreateFromPK11SlotInfo(NSSTrustDomain *td, PK11SlotInfo *nss3slot) 1.110 +{ 1.111 + NSSSlot *rvSlot; 1.112 + NSSArena *arena; 1.113 + arena = nssArena_Create(); 1.114 + if (!arena) { 1.115 + return NULL; 1.116 + } 1.117 + rvSlot = nss_ZNEW(arena, NSSSlot); 1.118 + if (!rvSlot) { 1.119 + nssArena_Destroy(arena); 1.120 + return NULL; 1.121 + } 1.122 + rvSlot->base.refCount = 1; 1.123 + rvSlot->base.lock = PZ_NewLock(nssILockOther); 1.124 + rvSlot->base.arena = arena; 1.125 + rvSlot->pk11slot = nss3slot; 1.126 + rvSlot->epv = nss3slot->functionList; 1.127 + rvSlot->slotID = nss3slot->slotID; 1.128 + /* Grab the slot name from the PKCS#11 fixed-length buffer */ 1.129 + rvSlot->base.name = nssUTF8_Duplicate(nss3slot->slot_name,td->arena); 1.130 + rvSlot->lock = (nss3slot->isThreadSafe) ? NULL : nss3slot->sessionLock; 1.131 + return rvSlot; 1.132 +} 1.133 + 1.134 +NSSToken * 1.135 +nssToken_CreateFromPK11SlotInfo(NSSTrustDomain *td, PK11SlotInfo *nss3slot) 1.136 +{ 1.137 + NSSToken *rvToken; 1.138 + NSSArena *arena; 1.139 + 1.140 + /* Don't create a token object for a disabled slot */ 1.141 + if (nss3slot->disabled) { 1.142 + PORT_SetError(SEC_ERROR_NO_TOKEN); 1.143 + return NULL; 1.144 + } 1.145 + arena = nssArena_Create(); 1.146 + if (!arena) { 1.147 + return NULL; 1.148 + } 1.149 + rvToken = nss_ZNEW(arena, NSSToken); 1.150 + if (!rvToken) { 1.151 + nssArena_Destroy(arena); 1.152 + return NULL; 1.153 + } 1.154 + rvToken->base.refCount = 1; 1.155 + rvToken->base.lock = PZ_NewLock(nssILockOther); 1.156 + if (!rvToken->base.lock) { 1.157 + nssArena_Destroy(arena); 1.158 + return NULL; 1.159 + } 1.160 + rvToken->base.arena = arena; 1.161 + rvToken->pk11slot = nss3slot; 1.162 + rvToken->epv = nss3slot->functionList; 1.163 + rvToken->defaultSession = nssSession_ImportNSS3Session(td->arena, 1.164 + nss3slot->session, 1.165 + nss3slot->sessionLock, 1.166 + nss3slot->defRWSession); 1.167 +#if 0 /* we should do this instead of blindly continuing. */ 1.168 + if (!rvToken->defaultSession) { 1.169 + PORT_SetError(SEC_ERROR_NO_TOKEN); 1.170 + goto loser; 1.171 + } 1.172 +#endif 1.173 + if (!PK11_IsInternal(nss3slot) && PK11_IsHW(nss3slot)) { 1.174 + rvToken->cache = nssTokenObjectCache_Create(rvToken, 1.175 + PR_TRUE, PR_TRUE, PR_TRUE); 1.176 + if (!rvToken->cache) 1.177 + goto loser; 1.178 + } 1.179 + rvToken->trustDomain = td; 1.180 + /* Grab the token name from the PKCS#11 fixed-length buffer */ 1.181 + rvToken->base.name = nssUTF8_Duplicate(nss3slot->token_name,td->arena); 1.182 + rvToken->slot = nssSlot_CreateFromPK11SlotInfo(td, nss3slot); 1.183 + if (!rvToken->slot) { 1.184 + goto loser; 1.185 + } 1.186 + rvToken->slot->token = rvToken; 1.187 + if (rvToken->defaultSession) 1.188 + rvToken->defaultSession->slot = rvToken->slot; 1.189 + return rvToken; 1.190 +loser: 1.191 + PZ_DestroyLock(rvToken->base.lock); 1.192 + nssArena_Destroy(arena); 1.193 + return NULL; 1.194 +} 1.195 + 1.196 +NSS_IMPLEMENT void 1.197 +nssToken_UpdateName(NSSToken *token) 1.198 +{ 1.199 + if (!token) { 1.200 + return; 1.201 + } 1.202 + token->base.name = nssUTF8_Duplicate(token->pk11slot->token_name,token->base.arena); 1.203 +} 1.204 + 1.205 +NSS_IMPLEMENT PRBool 1.206 +nssSlot_IsPermanent 1.207 +( 1.208 + NSSSlot *slot 1.209 +) 1.210 +{ 1.211 + return slot->pk11slot->isPerm; 1.212 +} 1.213 + 1.214 +NSS_IMPLEMENT PRBool 1.215 +nssSlot_IsFriendly 1.216 +( 1.217 + NSSSlot *slot 1.218 +) 1.219 +{ 1.220 + return PK11_IsFriendly(slot->pk11slot); 1.221 +} 1.222 + 1.223 +NSS_IMPLEMENT PRStatus 1.224 +nssToken_Refresh(NSSToken *token) 1.225 +{ 1.226 + PK11SlotInfo *nss3slot; 1.227 + 1.228 + if (!token) { 1.229 + return PR_SUCCESS; 1.230 + } 1.231 + nss3slot = token->pk11slot; 1.232 + token->defaultSession = 1.233 + nssSession_ImportNSS3Session(token->slot->base.arena, 1.234 + nss3slot->session, 1.235 + nss3slot->sessionLock, 1.236 + nss3slot->defRWSession); 1.237 + return token->defaultSession ? PR_SUCCESS : PR_FAILURE; 1.238 +} 1.239 + 1.240 +NSS_IMPLEMENT PRStatus 1.241 +nssSlot_Refresh 1.242 +( 1.243 + NSSSlot *slot 1.244 +) 1.245 +{ 1.246 + PK11SlotInfo *nss3slot = slot->pk11slot; 1.247 + PRBool doit = PR_FALSE; 1.248 + if (slot->token && slot->token->base.name[0] == 0) { 1.249 + doit = PR_TRUE; 1.250 + } 1.251 + if (PK11_InitToken(nss3slot, PR_FALSE) != SECSuccess) { 1.252 + return PR_FAILURE; 1.253 + } 1.254 + if (doit) { 1.255 + nssTrustDomain_UpdateCachedTokenCerts(slot->token->trustDomain, 1.256 + slot->token); 1.257 + } 1.258 + return nssToken_Refresh(slot->token); 1.259 +} 1.260 + 1.261 +NSS_IMPLEMENT PRStatus 1.262 +nssToken_GetTrustOrder 1.263 +( 1.264 + NSSToken *tok 1.265 +) 1.266 +{ 1.267 + PK11SlotInfo *slot; 1.268 + SECMODModule *module; 1.269 + slot = tok->pk11slot; 1.270 + module = PK11_GetModule(slot); 1.271 + return module->trustOrder; 1.272 +} 1.273 + 1.274 +NSS_IMPLEMENT PRBool 1.275 +nssSlot_IsLoggedIn 1.276 +( 1.277 + NSSSlot *slot 1.278 +) 1.279 +{ 1.280 + if (!slot->pk11slot->needLogin) { 1.281 + return PR_TRUE; 1.282 + } 1.283 + return PK11_IsLoggedIn(slot->pk11slot, NULL); 1.284 +} 1.285 + 1.286 + 1.287 +NSSTrustDomain * 1.288 +nssToken_GetTrustDomain(NSSToken *token) 1.289 +{ 1.290 + return token->trustDomain; 1.291 +} 1.292 + 1.293 +NSS_EXTERN PRStatus 1.294 +nssTrustDomain_RemoveTokenCertsFromCache 1.295 +( 1.296 + NSSTrustDomain *td, 1.297 + NSSToken *token 1.298 +); 1.299 + 1.300 +NSS_IMPLEMENT PRStatus 1.301 +nssToken_NotifyCertsNotVisible 1.302 +( 1.303 + NSSToken *tok 1.304 +) 1.305 +{ 1.306 + return nssTrustDomain_RemoveTokenCertsFromCache(tok->trustDomain, tok); 1.307 +} 1.308 +