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 $ $Date: 2005/01/20 02:25:48 $";
00039 #endif /* DEBUG */
00040 
00041 #ifndef NSS_3_4_CODE
00042 #define NSS_3_4_CODE
00043 #endif /* NSS_3_4_CODE */
00044 
00045 #ifndef PKIT_H
00046 #include "pkit.h"
00047 #endif /* PKIT_H */
00048 
00049 #ifndef DEVM_H
00050 #include "devm.h"
00051 #endif /* DEVM_H */
00052 
00053 #include "pki3hack.h"
00054 #include "dev3hack.h"
00055 #include "pkim.h"
00056 
00057 #ifndef BASE_H
00058 #include "base.h"
00059 #endif /* BASE_H */
00060 
00061 #include "pk11func.h"
00062 #include "secmodti.h"
00063 
00064 NSS_IMPLEMENT nssSession *
00065 nssSession_ImportNSS3Session(NSSArena *arenaOpt,
00066                              CK_SESSION_HANDLE session, 
00067                              PZLock *lock, PRBool rw)
00068 {
00069     nssSession *rvSession;
00070     rvSession = nss_ZNEW(arenaOpt, nssSession);
00071     rvSession->handle = session;
00072     rvSession->lock = lock;
00073     rvSession->ownLock = PR_FALSE;
00074     rvSession->isRW = rw;
00075     return rvSession;
00076 }
00077 
00078 NSS_IMPLEMENT nssSession *
00079 nssSlot_CreateSession
00080 (
00081   NSSSlot *slot,
00082   NSSArena *arenaOpt,
00083   PRBool readWrite
00084 )
00085 {
00086     nssSession *rvSession;
00087     rvSession = nss_ZNEW(arenaOpt, nssSession);
00088     if (!rvSession) {
00089        return (nssSession *)NULL;
00090     }
00091     if (readWrite) {
00092        rvSession->handle = PK11_GetRWSession(slot->pk11slot);
00093        if (rvSession->handle == CK_INVALID_HANDLE) {
00094            nss_ZFreeIf(rvSession);
00095            return NULL;
00096        }
00097        rvSession->isRW = PR_TRUE;
00098        rvSession->slot = slot;
00099         /*
00100          * The session doesn't need its own lock.  Here's why.
00101          * 1. If we are reusing the default RW session of the slot,
00102          *    the slot lock is already locked to protect the session.
00103          * 2. If the module is not thread safe, the slot (or rather
00104          *    module) lock is already locked.
00105          * 3. If the module is thread safe and we are using a new
00106          *    session, no higher-level lock has been locked and we
00107          *    would need a lock for the new session.  However, the
00108          *    NSS_3_4_CODE usage of the session is that it is always
00109          *    used and destroyed within the same function and never
00110          *    shared with another thread.
00111          * So the session is either already protected by another
00112          * lock or only used by one thread.
00113          */
00114         rvSession->lock = NULL;
00115         rvSession->ownLock = PR_FALSE;
00116        return rvSession;
00117     } else {
00118        return NULL;
00119     }
00120 }
00121 
00122 NSS_IMPLEMENT PRStatus
00123 nssSession_Destroy
00124 (
00125   nssSession *s
00126 )
00127 {
00128     CK_RV ckrv = CKR_OK;
00129     if (s) {
00130        if (s->isRW) {
00131            PK11_RestoreROSession(s->slot->pk11slot, s->handle);
00132        }
00133        nss_ZFreeIf(s);
00134     }
00135     return (ckrv == CKR_OK) ? PR_SUCCESS : PR_FAILURE;
00136 }
00137 
00138 static NSSSlot *
00139 nssSlot_CreateFromPK11SlotInfo(NSSTrustDomain *td, PK11SlotInfo *nss3slot)
00140 {
00141     NSSSlot *rvSlot;
00142     NSSArena *arena;
00143     arena = nssArena_Create();
00144     if (!arena) {
00145        return NULL;
00146     }
00147     rvSlot = nss_ZNEW(arena, NSSSlot);
00148     if (!rvSlot) {
00149        nssArena_Destroy(arena);
00150        return NULL;
00151     }
00152     rvSlot->base.refCount = 1;
00153     rvSlot->base.lock = PZ_NewLock(nssILockOther);
00154     rvSlot->base.arena = arena;
00155     rvSlot->pk11slot = nss3slot;
00156     rvSlot->epv = nss3slot->functionList;
00157     rvSlot->slotID = nss3slot->slotID;
00158     /* Grab the slot name from the PKCS#11 fixed-length buffer */
00159     rvSlot->base.name = nssUTF8_Duplicate(nss3slot->slot_name,td->arena);
00160     rvSlot->lock = (nss3slot->isThreadSafe) ? NULL : nss3slot->sessionLock;
00161     return rvSlot;
00162 }
00163 
00164 NSS_IMPLEMENT NSSToken *
00165 nssToken_CreateFromPK11SlotInfo(NSSTrustDomain *td, PK11SlotInfo *nss3slot)
00166 {
00167     NSSToken *rvToken;
00168     NSSArena *arena;
00169     arena = nssArena_Create();
00170     if (!arena) {
00171        return NULL;
00172     }
00173     rvToken = nss_ZNEW(arena, NSSToken);
00174     if (!rvToken) {
00175        nssArena_Destroy(arena);
00176        return NULL;
00177     }
00178     rvToken->base.refCount = 1;
00179     rvToken->base.lock = PZ_NewLock(nssILockOther);
00180     rvToken->base.arena = arena;
00181     rvToken->pk11slot = nss3slot;
00182     rvToken->epv = nss3slot->functionList;
00183     rvToken->defaultSession = nssSession_ImportNSS3Session(td->arena,
00184                                                        nss3slot->session,
00185                                                        nss3slot->sessionLock,
00186                                                        nss3slot->defRWSession);
00187     /* The above test was used in 3.4, for this cache have it always on */
00188     if (!PK11_IsInternal(nss3slot) && PK11_IsHW(nss3slot)) {
00189        rvToken->cache = nssTokenObjectCache_Create(rvToken, 
00190                                                    PR_TRUE, PR_TRUE, PR_TRUE);
00191        if (!rvToken->cache) {
00192            nssArena_Destroy(arena);
00193            return (NSSToken *)NULL;
00194        }
00195     }
00196     rvToken->trustDomain = td;
00197     /* Grab the token name from the PKCS#11 fixed-length buffer */
00198     rvToken->base.name = nssUTF8_Duplicate(nss3slot->token_name,td->arena);
00199     rvToken->slot = nssSlot_CreateFromPK11SlotInfo(td, nss3slot);
00200     rvToken->slot->token = rvToken;
00201     rvToken->defaultSession->slot = rvToken->slot;
00202     return rvToken;
00203 }
00204 
00205 NSS_IMPLEMENT void
00206 nssToken_UpdateName(NSSToken *token)
00207 {
00208     if (!token) {
00209        return;
00210     }
00211     token->base.name = nssUTF8_Duplicate(token->pk11slot->token_name,token->base.arena);
00212 }
00213 
00214 NSS_IMPLEMENT PRBool
00215 nssSlot_IsPermanent
00216 (
00217   NSSSlot *slot
00218 )
00219 {
00220     return slot->pk11slot->isPerm;
00221 }
00222 
00223 NSS_IMPLEMENT PRBool
00224 nssSlot_IsFriendly
00225 (
00226   NSSSlot *slot
00227 )
00228 {
00229     return PK11_IsFriendly(slot->pk11slot);
00230 }
00231 
00232 NSS_IMPLEMENT PRStatus
00233 nssToken_Refresh(NSSToken *token)
00234 {
00235     PK11SlotInfo *nss3slot;
00236 
00237     if (!token) {
00238        return PR_SUCCESS;
00239     }
00240     nss3slot = token->pk11slot;
00241     token->defaultSession = nssSession_ImportNSS3Session(token->slot->base.arena,
00242                                                        nss3slot->session,
00243                                                        nss3slot->sessionLock,
00244                                                        nss3slot->defRWSession);
00245     return PR_SUCCESS;
00246 }
00247 
00248 NSS_IMPLEMENT PRStatus
00249 nssSlot_Refresh
00250 (
00251   NSSSlot *slot
00252 )
00253 {
00254     PK11SlotInfo *nss3slot = slot->pk11slot;
00255     PRBool doit = PR_FALSE;
00256     if (slot->token->base.name[0] == 0) {
00257        doit = PR_TRUE;
00258     }
00259     if (PK11_InitToken(nss3slot, PR_FALSE) != SECSuccess) {
00260        return PR_FAILURE;
00261     }
00262     if (doit) {
00263        nssTrustDomain_UpdateCachedTokenCerts(slot->token->trustDomain, 
00264                                              slot->token);
00265     }
00266     return nssToken_Refresh(slot->token);
00267 }
00268 
00269 NSS_IMPLEMENT PRStatus
00270 nssToken_GetTrustOrder
00271 (
00272   NSSToken *tok
00273 )
00274 {
00275     PK11SlotInfo *slot;
00276     SECMODModule *module;
00277     slot = tok->pk11slot;
00278     module = PK11_GetModule(slot);
00279     return module->trustOrder;
00280 }
00281 
00282 NSS_IMPLEMENT PRBool
00283 nssSlot_IsLoggedIn
00284 (
00285   NSSSlot *slot
00286 )
00287 {
00288     if (!slot->pk11slot->needLogin) {
00289        return PR_TRUE;
00290     }
00291     return PK11_IsLoggedIn(slot->pk11slot, NULL);
00292 }
00293 
00294 
00295 NSSTrustDomain *
00296 nssToken_GetTrustDomain(NSSToken *token)
00297 {
00298     return token->trustDomain;
00299 }
00300 
00301 NSS_EXTERN PRStatus
00302 nssTrustDomain_RemoveTokenCertsFromCache
00303 (
00304   NSSTrustDomain *td,
00305   NSSToken *token
00306 );
00307 
00308 NSS_IMPLEMENT PRStatus
00309 nssToken_NotifyCertsNotVisible
00310 (
00311   NSSToken *tok
00312 )
00313 {
00314     return nssTrustDomain_RemoveTokenCertsFromCache(tok->trustDomain, tok);
00315 }
00316