Back to index

lightning-sunbird  0.9+nobinonly
dev3hack.c
Go to the documentation of this file.
00001 /* ***** BEGIN LICENSE BLOCK *****
00002  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
00003  *
00004  * The contents of this file are subject to the Mozilla Public License Version
00005  * 1.1 (the "License"); you may not use this file except in compliance with
00006  * the License. You may obtain a copy of the License at
00007  * http://www.mozilla.org/MPL/
00008  *
00009  * Software distributed under the License is distributed on an "AS IS" basis,
00010  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
00011  * for the specific language governing rights and limitations under the
00012  * License.
00013  *
00014  * The Original Code is the Netscape security libraries.
00015  *
00016  * The Initial Developer of the Original Code is
00017  * Netscape Communications Corporation.
00018  * Portions created by the Initial Developer are Copyright (C) 1994-2000
00019  * the Initial Developer. All Rights Reserved.
00020  *
00021  * Contributor(s):
00022  *
00023  * Alternatively, the contents of this file may be used under the terms of
00024  * either the GNU General Public License Version 2 or later (the "GPL"), or
00025  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
00026  * in which case the provisions of the GPL or the LGPL are applicable instead
00027  * of those above. If you wish to allow use of your version of this file only
00028  * under the terms of either the GPL or the LGPL, and not to allow others to
00029  * use your version of this file under the terms of the MPL, indicate your
00030  * decision by deleting the provisions above and replace them with the notice
00031  * and other provisions required by the GPL or the LGPL. If you do not delete
00032  * the provisions above, a recipient may use your version of this file under
00033  * the terms of any one of the MPL, the GPL or the LGPL.
00034  *
00035  * ***** END LICENSE BLOCK ***** */
00036 
00037 #ifdef DEBUG
00038 static const char CVS_ID[] = "@(#) $RCSfile: dev3hack.c,v $ $Revision: 1.21.28.1 $ $Date: 2007/11/16 05:25:08 $";
00039 #endif /* DEBUG */
00040 
00041 #ifndef PKIT_H
00042 #include "pkit.h"
00043 #endif /* PKIT_H */
00044 
00045 #ifndef DEVM_H
00046 #include "devm.h"
00047 #endif /* DEVM_H */
00048 
00049 #include "pki3hack.h"
00050 #include "dev3hack.h"
00051 #include "pkim.h"
00052 
00053 #ifndef BASE_H
00054 #include "base.h"
00055 #endif /* BASE_H */
00056 
00057 #include "pk11func.h"
00058 #include "secmodti.h"
00059 
00060 NSS_IMPLEMENT nssSession *
00061 nssSession_ImportNSS3Session(NSSArena *arenaOpt,
00062                              CK_SESSION_HANDLE session, 
00063                              PZLock *lock, PRBool rw)
00064 {
00065     nssSession *rvSession;
00066     rvSession = nss_ZNEW(arenaOpt, nssSession);
00067     rvSession->handle = session;
00068     rvSession->lock = lock;
00069     rvSession->ownLock = PR_FALSE;
00070     rvSession->isRW = rw;
00071     return rvSession;
00072 }
00073 
00074 NSS_IMPLEMENT nssSession *
00075 nssSlot_CreateSession
00076 (
00077   NSSSlot *slot,
00078   NSSArena *arenaOpt,
00079   PRBool readWrite
00080 )
00081 {
00082     nssSession *rvSession;
00083     rvSession = nss_ZNEW(arenaOpt, nssSession);
00084     if (!rvSession) {
00085        return (nssSession *)NULL;
00086     }
00087     if (readWrite) {
00088        rvSession->handle = PK11_GetRWSession(slot->pk11slot);
00089        if (rvSession->handle == CK_INVALID_HANDLE) {
00090            nss_ZFreeIf(rvSession);
00091            return NULL;
00092        }
00093        rvSession->isRW = PR_TRUE;
00094        rvSession->slot = slot;
00095         /*
00096          * The session doesn't need its own lock.  Here's why.
00097          * 1. If we are reusing the default RW session of the slot,
00098          *    the slot lock is already locked to protect the session.
00099          * 2. If the module is not thread safe, the slot (or rather
00100          *    module) lock is already locked.
00101          * 3. If the module is thread safe and we are using a new
00102          *    session, no higher-level lock has been locked and we
00103          *    would need a lock for the new session.  However, the
00104          *    current usage of the session is that it is always
00105          *    used and destroyed within the same function and never
00106          *    shared with another thread.
00107          * So the session is either already protected by another
00108          * lock or only used by one thread.
00109          */
00110         rvSession->lock = NULL;
00111         rvSession->ownLock = PR_FALSE;
00112        return rvSession;
00113     } else {
00114        return NULL;
00115     }
00116 }
00117 
00118 NSS_IMPLEMENT PRStatus
00119 nssSession_Destroy
00120 (
00121   nssSession *s
00122 )
00123 {
00124     CK_RV ckrv = CKR_OK;
00125     if (s) {
00126        if (s->isRW) {
00127            PK11_RestoreROSession(s->slot->pk11slot, s->handle);
00128        }
00129        nss_ZFreeIf(s);
00130     }
00131     return (ckrv == CKR_OK) ? PR_SUCCESS : PR_FAILURE;
00132 }
00133 
00134 static NSSSlot *
00135 nssSlot_CreateFromPK11SlotInfo(NSSTrustDomain *td, PK11SlotInfo *nss3slot)
00136 {
00137     NSSSlot *rvSlot;
00138     NSSArena *arena;
00139     arena = nssArena_Create();
00140     if (!arena) {
00141        return NULL;
00142     }
00143     rvSlot = nss_ZNEW(arena, NSSSlot);
00144     if (!rvSlot) {
00145        nssArena_Destroy(arena);
00146        return NULL;
00147     }
00148     rvSlot->base.refCount = 1;
00149     rvSlot->base.lock = PZ_NewLock(nssILockOther);
00150     rvSlot->base.arena = arena;
00151     rvSlot->pk11slot = nss3slot;
00152     rvSlot->epv = nss3slot->functionList;
00153     rvSlot->slotID = nss3slot->slotID;
00154     /* Grab the slot name from the PKCS#11 fixed-length buffer */
00155     rvSlot->base.name = nssUTF8_Duplicate(nss3slot->slot_name,td->arena);
00156     rvSlot->lock = (nss3slot->isThreadSafe) ? NULL : nss3slot->sessionLock;
00157     return rvSlot;
00158 }
00159 
00160 NSS_IMPLEMENT NSSToken *
00161 nssToken_CreateFromPK11SlotInfo(NSSTrustDomain *td, PK11SlotInfo *nss3slot)
00162 {
00163     NSSToken *rvToken;
00164     NSSArena *arena;
00165     arena = nssArena_Create();
00166     if (!arena) {
00167        return NULL;
00168     }
00169     rvToken = nss_ZNEW(arena, NSSToken);
00170     if (!rvToken) {
00171        nssArena_Destroy(arena);
00172        return NULL;
00173     }
00174     rvToken->base.refCount = 1;
00175     rvToken->base.lock = PZ_NewLock(nssILockOther);
00176     rvToken->base.arena = arena;
00177     rvToken->pk11slot = nss3slot;
00178     rvToken->epv = nss3slot->functionList;
00179     rvToken->defaultSession = nssSession_ImportNSS3Session(td->arena,
00180                                                        nss3slot->session,
00181                                                        nss3slot->sessionLock,
00182                                                        nss3slot->defRWSession);
00183     /* The above test was used in 3.4, for this cache have it always on */
00184     if (!PK11_IsInternal(nss3slot) && PK11_IsHW(nss3slot)) {
00185        rvToken->cache = nssTokenObjectCache_Create(rvToken, 
00186                                                    PR_TRUE, PR_TRUE, PR_TRUE);
00187        if (!rvToken->cache) {
00188            nssArena_Destroy(arena);
00189            return (NSSToken *)NULL;
00190        }
00191     }
00192     rvToken->trustDomain = td;
00193     /* Grab the token name from the PKCS#11 fixed-length buffer */
00194     rvToken->base.name = nssUTF8_Duplicate(nss3slot->token_name,td->arena);
00195     rvToken->slot = nssSlot_CreateFromPK11SlotInfo(td, nss3slot);
00196     rvToken->slot->token = rvToken;
00197     rvToken->defaultSession->slot = rvToken->slot;
00198     return rvToken;
00199 }
00200 
00201 NSS_IMPLEMENT void
00202 nssToken_UpdateName(NSSToken *token)
00203 {
00204     if (!token) {
00205        return;
00206     }
00207     token->base.name = nssUTF8_Duplicate(token->pk11slot->token_name,token->base.arena);
00208 }
00209 
00210 NSS_IMPLEMENT PRBool
00211 nssSlot_IsPermanent
00212 (
00213   NSSSlot *slot
00214 )
00215 {
00216     return slot->pk11slot->isPerm;
00217 }
00218 
00219 NSS_IMPLEMENT PRBool
00220 nssSlot_IsFriendly
00221 (
00222   NSSSlot *slot
00223 )
00224 {
00225     return PK11_IsFriendly(slot->pk11slot);
00226 }
00227 
00228 NSS_IMPLEMENT PRStatus
00229 nssToken_Refresh(NSSToken *token)
00230 {
00231     PK11SlotInfo *nss3slot;
00232 
00233     if (!token) {
00234        return PR_SUCCESS;
00235     }
00236     nss3slot = token->pk11slot;
00237     token->defaultSession = nssSession_ImportNSS3Session(token->slot->base.arena,
00238                                                        nss3slot->session,
00239                                                        nss3slot->sessionLock,
00240                                                        nss3slot->defRWSession);
00241     return PR_SUCCESS;
00242 }
00243 
00244 NSS_IMPLEMENT PRStatus
00245 nssSlot_Refresh
00246 (
00247   NSSSlot *slot
00248 )
00249 {
00250     PK11SlotInfo *nss3slot = slot->pk11slot;
00251     PRBool doit = PR_FALSE;
00252     if (slot->token->base.name[0] == 0) {
00253        doit = PR_TRUE;
00254     }
00255     if (PK11_InitToken(nss3slot, PR_FALSE) != SECSuccess) {
00256        return PR_FAILURE;
00257     }
00258     if (doit) {
00259        nssTrustDomain_UpdateCachedTokenCerts(slot->token->trustDomain, 
00260                                              slot->token);
00261     }
00262     return nssToken_Refresh(slot->token);
00263 }
00264 
00265 NSS_IMPLEMENT PRStatus
00266 nssToken_GetTrustOrder
00267 (
00268   NSSToken *tok
00269 )
00270 {
00271     PK11SlotInfo *slot;
00272     SECMODModule *module;
00273     slot = tok->pk11slot;
00274     module = PK11_GetModule(slot);
00275     return module->trustOrder;
00276 }
00277 
00278 NSS_IMPLEMENT PRBool
00279 nssSlot_IsLoggedIn
00280 (
00281   NSSSlot *slot
00282 )
00283 {
00284     if (!slot->pk11slot->needLogin) {
00285        return PR_TRUE;
00286     }
00287     return PK11_IsLoggedIn(slot->pk11slot, NULL);
00288 }
00289 
00290 
00291 NSSTrustDomain *
00292 nssToken_GetTrustDomain(NSSToken *token)
00293 {
00294     return token->trustDomain;
00295 }
00296 
00297 NSS_EXTERN PRStatus
00298 nssTrustDomain_RemoveTokenCertsFromCache
00299 (
00300   NSSTrustDomain *td,
00301   NSSToken *token
00302 );
00303 
00304 NSS_IMPLEMENT PRStatus
00305 nssToken_NotifyCertsNotVisible
00306 (
00307   NSSToken *tok
00308 )
00309 {
00310     return nssTrustDomain_RemoveTokenCertsFromCache(tok->trustDomain, tok);
00311 }
00312