security/nss/lib/pk11wrap/dev3hack.c

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

michael@0 1 /* This Source Code Form is subject to the terms of the Mozilla Public
michael@0 2 * License, v. 2.0. If a copy of the MPL was not distributed with this
michael@0 3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
michael@0 4
michael@0 5 #ifndef PKIT_H
michael@0 6 #include "pkit.h"
michael@0 7 #endif /* PKIT_H */
michael@0 8
michael@0 9 #ifndef DEVM_H
michael@0 10 #include "devm.h"
michael@0 11 #endif /* DEVM_H */
michael@0 12
michael@0 13 #include "pki3hack.h"
michael@0 14 #include "dev3hack.h"
michael@0 15 #include "pkim.h"
michael@0 16
michael@0 17 #ifndef BASE_H
michael@0 18 #include "base.h"
michael@0 19 #endif /* BASE_H */
michael@0 20
michael@0 21 #include "pk11func.h"
michael@0 22 #include "secmodti.h"
michael@0 23 #include "secerr.h"
michael@0 24
michael@0 25 NSS_IMPLEMENT nssSession *
michael@0 26 nssSession_ImportNSS3Session(NSSArena *arenaOpt,
michael@0 27 CK_SESSION_HANDLE session,
michael@0 28 PZLock *lock, PRBool rw)
michael@0 29 {
michael@0 30 nssSession *rvSession = NULL;
michael@0 31 if (session != CK_INVALID_SESSION) {
michael@0 32 rvSession = nss_ZNEW(arenaOpt, nssSession);
michael@0 33 if (rvSession) {
michael@0 34 rvSession->handle = session;
michael@0 35 rvSession->lock = lock;
michael@0 36 rvSession->ownLock = PR_FALSE;
michael@0 37 rvSession->isRW = rw;
michael@0 38 }
michael@0 39 }
michael@0 40 return rvSession;
michael@0 41 }
michael@0 42
michael@0 43 NSS_IMPLEMENT nssSession *
michael@0 44 nssSlot_CreateSession
michael@0 45 (
michael@0 46 NSSSlot *slot,
michael@0 47 NSSArena *arenaOpt,
michael@0 48 PRBool readWrite
michael@0 49 )
michael@0 50 {
michael@0 51 nssSession *rvSession;
michael@0 52
michael@0 53 if (!readWrite) {
michael@0 54 /* nss3hack version only returns rw swssions */
michael@0 55 return NULL;
michael@0 56 }
michael@0 57 rvSession = nss_ZNEW(arenaOpt, nssSession);
michael@0 58 if (!rvSession) {
michael@0 59 return (nssSession *)NULL;
michael@0 60 }
michael@0 61
michael@0 62 rvSession->handle = PK11_GetRWSession(slot->pk11slot);
michael@0 63 if (rvSession->handle == CK_INVALID_HANDLE) {
michael@0 64 nss_ZFreeIf(rvSession);
michael@0 65 return NULL;
michael@0 66 }
michael@0 67 rvSession->isRW = PR_TRUE;
michael@0 68 rvSession->slot = slot;
michael@0 69 /*
michael@0 70 * The session doesn't need its own lock. Here's why.
michael@0 71 * 1. If we are reusing the default RW session of the slot,
michael@0 72 * the slot lock is already locked to protect the session.
michael@0 73 * 2. If the module is not thread safe, the slot (or rather
michael@0 74 * module) lock is already locked.
michael@0 75 * 3. If the module is thread safe and we are using a new
michael@0 76 * session, no higher-level lock has been locked and we
michael@0 77 * would need a lock for the new session. However, the
michael@0 78 * current usage of the session is that it is always
michael@0 79 * used and destroyed within the same function and never
michael@0 80 * shared with another thread.
michael@0 81 * So the session is either already protected by another
michael@0 82 * lock or only used by one thread.
michael@0 83 */
michael@0 84 rvSession->lock = NULL;
michael@0 85 rvSession->ownLock = PR_FALSE;
michael@0 86 return rvSession;
michael@0 87 }
michael@0 88
michael@0 89 NSS_IMPLEMENT PRStatus
michael@0 90 nssSession_Destroy
michael@0 91 (
michael@0 92 nssSession *s
michael@0 93 )
michael@0 94 {
michael@0 95 CK_RV ckrv = CKR_OK;
michael@0 96 if (s) {
michael@0 97 if (s->isRW) {
michael@0 98 PK11_RestoreROSession(s->slot->pk11slot, s->handle);
michael@0 99 }
michael@0 100 nss_ZFreeIf(s);
michael@0 101 }
michael@0 102 return (ckrv == CKR_OK) ? PR_SUCCESS : PR_FAILURE;
michael@0 103 }
michael@0 104
michael@0 105 static NSSSlot *
michael@0 106 nssSlot_CreateFromPK11SlotInfo(NSSTrustDomain *td, PK11SlotInfo *nss3slot)
michael@0 107 {
michael@0 108 NSSSlot *rvSlot;
michael@0 109 NSSArena *arena;
michael@0 110 arena = nssArena_Create();
michael@0 111 if (!arena) {
michael@0 112 return NULL;
michael@0 113 }
michael@0 114 rvSlot = nss_ZNEW(arena, NSSSlot);
michael@0 115 if (!rvSlot) {
michael@0 116 nssArena_Destroy(arena);
michael@0 117 return NULL;
michael@0 118 }
michael@0 119 rvSlot->base.refCount = 1;
michael@0 120 rvSlot->base.lock = PZ_NewLock(nssILockOther);
michael@0 121 rvSlot->base.arena = arena;
michael@0 122 rvSlot->pk11slot = nss3slot;
michael@0 123 rvSlot->epv = nss3slot->functionList;
michael@0 124 rvSlot->slotID = nss3slot->slotID;
michael@0 125 /* Grab the slot name from the PKCS#11 fixed-length buffer */
michael@0 126 rvSlot->base.name = nssUTF8_Duplicate(nss3slot->slot_name,td->arena);
michael@0 127 rvSlot->lock = (nss3slot->isThreadSafe) ? NULL : nss3slot->sessionLock;
michael@0 128 return rvSlot;
michael@0 129 }
michael@0 130
michael@0 131 NSSToken *
michael@0 132 nssToken_CreateFromPK11SlotInfo(NSSTrustDomain *td, PK11SlotInfo *nss3slot)
michael@0 133 {
michael@0 134 NSSToken *rvToken;
michael@0 135 NSSArena *arena;
michael@0 136
michael@0 137 /* Don't create a token object for a disabled slot */
michael@0 138 if (nss3slot->disabled) {
michael@0 139 PORT_SetError(SEC_ERROR_NO_TOKEN);
michael@0 140 return NULL;
michael@0 141 }
michael@0 142 arena = nssArena_Create();
michael@0 143 if (!arena) {
michael@0 144 return NULL;
michael@0 145 }
michael@0 146 rvToken = nss_ZNEW(arena, NSSToken);
michael@0 147 if (!rvToken) {
michael@0 148 nssArena_Destroy(arena);
michael@0 149 return NULL;
michael@0 150 }
michael@0 151 rvToken->base.refCount = 1;
michael@0 152 rvToken->base.lock = PZ_NewLock(nssILockOther);
michael@0 153 if (!rvToken->base.lock) {
michael@0 154 nssArena_Destroy(arena);
michael@0 155 return NULL;
michael@0 156 }
michael@0 157 rvToken->base.arena = arena;
michael@0 158 rvToken->pk11slot = nss3slot;
michael@0 159 rvToken->epv = nss3slot->functionList;
michael@0 160 rvToken->defaultSession = nssSession_ImportNSS3Session(td->arena,
michael@0 161 nss3slot->session,
michael@0 162 nss3slot->sessionLock,
michael@0 163 nss3slot->defRWSession);
michael@0 164 #if 0 /* we should do this instead of blindly continuing. */
michael@0 165 if (!rvToken->defaultSession) {
michael@0 166 PORT_SetError(SEC_ERROR_NO_TOKEN);
michael@0 167 goto loser;
michael@0 168 }
michael@0 169 #endif
michael@0 170 if (!PK11_IsInternal(nss3slot) && PK11_IsHW(nss3slot)) {
michael@0 171 rvToken->cache = nssTokenObjectCache_Create(rvToken,
michael@0 172 PR_TRUE, PR_TRUE, PR_TRUE);
michael@0 173 if (!rvToken->cache)
michael@0 174 goto loser;
michael@0 175 }
michael@0 176 rvToken->trustDomain = td;
michael@0 177 /* Grab the token name from the PKCS#11 fixed-length buffer */
michael@0 178 rvToken->base.name = nssUTF8_Duplicate(nss3slot->token_name,td->arena);
michael@0 179 rvToken->slot = nssSlot_CreateFromPK11SlotInfo(td, nss3slot);
michael@0 180 if (!rvToken->slot) {
michael@0 181 goto loser;
michael@0 182 }
michael@0 183 rvToken->slot->token = rvToken;
michael@0 184 if (rvToken->defaultSession)
michael@0 185 rvToken->defaultSession->slot = rvToken->slot;
michael@0 186 return rvToken;
michael@0 187 loser:
michael@0 188 PZ_DestroyLock(rvToken->base.lock);
michael@0 189 nssArena_Destroy(arena);
michael@0 190 return NULL;
michael@0 191 }
michael@0 192
michael@0 193 NSS_IMPLEMENT void
michael@0 194 nssToken_UpdateName(NSSToken *token)
michael@0 195 {
michael@0 196 if (!token) {
michael@0 197 return;
michael@0 198 }
michael@0 199 token->base.name = nssUTF8_Duplicate(token->pk11slot->token_name,token->base.arena);
michael@0 200 }
michael@0 201
michael@0 202 NSS_IMPLEMENT PRBool
michael@0 203 nssSlot_IsPermanent
michael@0 204 (
michael@0 205 NSSSlot *slot
michael@0 206 )
michael@0 207 {
michael@0 208 return slot->pk11slot->isPerm;
michael@0 209 }
michael@0 210
michael@0 211 NSS_IMPLEMENT PRBool
michael@0 212 nssSlot_IsFriendly
michael@0 213 (
michael@0 214 NSSSlot *slot
michael@0 215 )
michael@0 216 {
michael@0 217 return PK11_IsFriendly(slot->pk11slot);
michael@0 218 }
michael@0 219
michael@0 220 NSS_IMPLEMENT PRStatus
michael@0 221 nssToken_Refresh(NSSToken *token)
michael@0 222 {
michael@0 223 PK11SlotInfo *nss3slot;
michael@0 224
michael@0 225 if (!token) {
michael@0 226 return PR_SUCCESS;
michael@0 227 }
michael@0 228 nss3slot = token->pk11slot;
michael@0 229 token->defaultSession =
michael@0 230 nssSession_ImportNSS3Session(token->slot->base.arena,
michael@0 231 nss3slot->session,
michael@0 232 nss3slot->sessionLock,
michael@0 233 nss3slot->defRWSession);
michael@0 234 return token->defaultSession ? PR_SUCCESS : PR_FAILURE;
michael@0 235 }
michael@0 236
michael@0 237 NSS_IMPLEMENT PRStatus
michael@0 238 nssSlot_Refresh
michael@0 239 (
michael@0 240 NSSSlot *slot
michael@0 241 )
michael@0 242 {
michael@0 243 PK11SlotInfo *nss3slot = slot->pk11slot;
michael@0 244 PRBool doit = PR_FALSE;
michael@0 245 if (slot->token && slot->token->base.name[0] == 0) {
michael@0 246 doit = PR_TRUE;
michael@0 247 }
michael@0 248 if (PK11_InitToken(nss3slot, PR_FALSE) != SECSuccess) {
michael@0 249 return PR_FAILURE;
michael@0 250 }
michael@0 251 if (doit) {
michael@0 252 nssTrustDomain_UpdateCachedTokenCerts(slot->token->trustDomain,
michael@0 253 slot->token);
michael@0 254 }
michael@0 255 return nssToken_Refresh(slot->token);
michael@0 256 }
michael@0 257
michael@0 258 NSS_IMPLEMENT PRStatus
michael@0 259 nssToken_GetTrustOrder
michael@0 260 (
michael@0 261 NSSToken *tok
michael@0 262 )
michael@0 263 {
michael@0 264 PK11SlotInfo *slot;
michael@0 265 SECMODModule *module;
michael@0 266 slot = tok->pk11slot;
michael@0 267 module = PK11_GetModule(slot);
michael@0 268 return module->trustOrder;
michael@0 269 }
michael@0 270
michael@0 271 NSS_IMPLEMENT PRBool
michael@0 272 nssSlot_IsLoggedIn
michael@0 273 (
michael@0 274 NSSSlot *slot
michael@0 275 )
michael@0 276 {
michael@0 277 if (!slot->pk11slot->needLogin) {
michael@0 278 return PR_TRUE;
michael@0 279 }
michael@0 280 return PK11_IsLoggedIn(slot->pk11slot, NULL);
michael@0 281 }
michael@0 282
michael@0 283
michael@0 284 NSSTrustDomain *
michael@0 285 nssToken_GetTrustDomain(NSSToken *token)
michael@0 286 {
michael@0 287 return token->trustDomain;
michael@0 288 }
michael@0 289
michael@0 290 NSS_EXTERN PRStatus
michael@0 291 nssTrustDomain_RemoveTokenCertsFromCache
michael@0 292 (
michael@0 293 NSSTrustDomain *td,
michael@0 294 NSSToken *token
michael@0 295 );
michael@0 296
michael@0 297 NSS_IMPLEMENT PRStatus
michael@0 298 nssToken_NotifyCertsNotVisible
michael@0 299 (
michael@0 300 NSSToken *tok
michael@0 301 )
michael@0 302 {
michael@0 303 return nssTrustDomain_RemoveTokenCertsFromCache(tok->trustDomain, tok);
michael@0 304 }
michael@0 305

mercurial