diff -up ./mozilla/security/nss/lib/pk11wrap/pk11pars.c.jss ./mozilla/security/nss/lib/pk11wrap/pk11pars.c --- ./mozilla/security/nss/lib/pk11wrap/pk11pars.c.jss 2011-02-11 07:45:38.324083242 -0800 +++ ./mozilla/security/nss/lib/pk11wrap/pk11pars.c 2011-02-11 07:48:14.514166538 -0800 @@ -258,6 +258,19 @@ secmod_IsInternalKeySlot(SECMODModule *m return (flags & SECMOD_FLAG_INTERNAL_KEY_SLOT) ? PR_TRUE : PR_FALSE; } +void +secmod_SetInternalKeySlotFlag(SECMODModule *mod, PRBool val) +{ + char flags = (char) mod->internal; + + if (val) { + flags |= SECMOD_FLAG_INTERNAL_KEY_SLOT; + } else { + flags &= ~SECMOD_FLAG_INTERNAL_KEY_SLOT; + } + mod->internal = flags; +} + /* forward declarations */ static int secmod_escapeSize(const char *string, char quote); static char *secmod_addEscape(const char *string, char quote); diff -up ./mozilla/security/nss/lib/pk11wrap/pk11priv.h.jss ./mozilla/security/nss/lib/pk11wrap/pk11priv.h --- ./mozilla/security/nss/lib/pk11wrap/pk11priv.h.jss 2011-02-11 07:47:45.037226877 -0800 +++ ./mozilla/security/nss/lib/pk11wrap/pk11priv.h 2011-02-11 07:48:28.854164207 -0800 @@ -115,6 +115,7 @@ void PK11_InitSlot(SECMODModule *mod,CK_ PRBool PK11_NeedPWInitForSlot(PK11SlotInfo *slot); SECStatus PK11_ReadSlotCerts(PK11SlotInfo *slot); void pk11_SetInternalKeySlot(PK11SlotInfo *slot); +PK11SlotInfo *pk11_SwapInternalKeySlot(PK11SlotInfo *slot); void pk11_SetInternalKeySlotIfFirst(PK11SlotInfo *slot); /********************************************************************* diff -up ./mozilla/security/nss/lib/pk11wrap/pk11slot.c.jss ./mozilla/security/nss/lib/pk11wrap/pk11slot.c --- ./mozilla/security/nss/lib/pk11wrap/pk11slot.c.jss 2011-02-11 07:41:11.258746774 -0800 +++ ./mozilla/security/nss/lib/pk11wrap/pk11slot.c 2011-02-11 07:48:51.291595867 -0800 @@ -1755,6 +1755,18 @@ pk11_SetInternalKeySlotIfFirst(PK11SlotI pk11InternalKeySlot = slot ? PK11_ReferenceSlot(slot) : NULL; } +/* + * Swap out a default internal keyslot. Caller owns the Slot Reference + */ +PK11SlotInfo * +pk11_SwapInternalKeySlot(PK11SlotInfo *slot) +{ + PK11SlotInfo *swap = pk11InternalKeySlot; + + pk11InternalKeySlot = slot ? PK11_ReferenceSlot(slot) : NULL; + return swap; +} + /* get the internal key slot. FIPS has only one slot for both key slots and * default slots */ diff -up ./mozilla/security/nss/lib/pk11wrap/pk11util.c.jss ./mozilla/security/nss/lib/pk11wrap/pk11util.c --- ./mozilla/security/nss/lib/pk11wrap/pk11util.c.jss 2011-02-11 07:40:23.748066635 -0800 +++ ./mozilla/security/nss/lib/pk11wrap/pk11util.c 2011-02-11 07:49:19.674611909 -0800 @@ -483,13 +483,25 @@ SECMOD_DeleteInternalModule(const char * NULL, SECMOD_FIPS_FLAGS); } if (newModule) { + PK11SlotInfo *slot; newModule->libraryParams = PORT_ArenaStrdup(newModule->arena,mlp->module->libraryParams); + /* if an explicit internal key slot has been set, reset it */ + slot = pk11_SwapInternalKeySlot(NULL); + if (slot) { + secmod_SetInternalKeySlotFlag(newModule, PR_TRUE); + } rv = SECMOD_AddModule(newModule); if (rv != SECSuccess) { + /* load failed, restore the internal key slot */ + pk11_SetInternalKeySlot(slot); SECMOD_DestroyModule(newModule); newModule = NULL; } + /* free the old explicit internal key slot, we now have a new one */ + if (slot) { + PK11_FreeSlot(slot); + } } if (newModule == NULL) { SECMODModuleList *last = NULL,*mlp2; diff -up ./mozilla/security/nss/lib/pk11wrap/secmodi.h.jss ./mozilla/security/nss/lib/pk11wrap/secmodi.h --- ./mozilla/security/nss/lib/pk11wrap/secmodi.h.jss 2011-02-11 07:39:04.685590962 -0800 +++ ./mozilla/security/nss/lib/pk11wrap/secmodi.h 2011-02-11 07:49:28.120021571 -0800 @@ -90,6 +90,8 @@ SECStatus secmod_LoadPKCS11Module(SECMOD SECStatus SECMOD_UnloadModule(SECMODModule *); void SECMOD_SetInternalModule(SECMODModule *); PRBool secmod_IsInternalKeySlot(SECMODModule *); +void secmod_SetInternalKeySlotFlag(SECMODModule *mod, PRBool val); + /* tools for checking if we are loading the same database twice */ typedef struct SECMODConfigListStr SECMODConfigList;