diff options
author | cvs2hg <devnull@localhost> | 2003-05-19 17:27:14 +0000 |
---|---|---|
committer | cvs2hg <devnull@localhost> | 2003-05-19 17:27:14 +0000 |
commit | f41bf619d6fc462202ac5598cccb7012a8aa9212 (patch) | |
tree | 7866a33c6072940e5db3cd3ea349e82038b00add | |
parent | 014cc87d40b6e622cd106e8323a5d3caafa613f1 (diff) | |
download | nss-hg-f41bf619d6fc462202ac5598cccb7012a8aa9212.tar.gz |
fixup commit for branch 'ANGELON_MOZ12_N7_BRANCH'PHT_20030522N7_WIN_FREEZEANGELON_MOZ12_N7_BASE
-rw-r--r-- | security/nss/cmd/lib/secutil.c | 64 | ||||
-rw-r--r-- | security/nss/cmd/selfserv/selfserv.c | 8 | ||||
-rw-r--r-- | security/nss/lib/dev/dev.h | 12 | ||||
-rw-r--r-- | security/nss/lib/dev/devslot.c | 35 | ||||
-rw-r--r-- | security/nss/lib/dev/devt.h | 2 | ||||
-rw-r--r-- | security/nss/lib/nss/nss.h | 6 | ||||
-rw-r--r-- | security/nss/lib/pk11wrap/dev3hack.c | 19 | ||||
-rw-r--r-- | security/nss/lib/pk11wrap/pk11func.h | 2 | ||||
-rw-r--r-- | security/nss/lib/pk11wrap/pk11load.c | 2 | ||||
-rw-r--r-- | security/nss/lib/pk11wrap/pk11slot.c | 23 | ||||
-rw-r--r-- | security/nss/lib/pk11wrap/pk11util.c | 6 | ||||
-rw-r--r-- | security/nss/lib/smime/cmsdecode.c | 68 | ||||
-rw-r--r-- | security/nss/lib/ssl/ssl.def | 6 | ||||
-rw-r--r-- | security/nss/lib/ssl/ssl.h | 5 | ||||
-rw-r--r-- | security/nss/lib/ssl/ssl3con.c | 30 | ||||
-rw-r--r-- | security/nss/lib/ssl/sslimpl.h | 3 | ||||
-rw-r--r-- | security/nss/lib/ssl/sslsnce.c | 16 | ||||
-rw-r--r-- | security/nss/lib/util/secasn1d.c | 58 |
18 files changed, 279 insertions, 86 deletions
diff --git a/security/nss/cmd/lib/secutil.c b/security/nss/cmd/lib/secutil.c index f205105e5..52d859bac 100644 --- a/security/nss/cmd/lib/secutil.c +++ b/security/nss/cmd/lib/secutil.c @@ -704,13 +704,13 @@ SECU_PrintAsHex(FILE *out, SECItem *data, const char *m, int level) } if (i != data->len - 1) { fprintf(out, "%02x:", data->data[i]); - column += 4; + column += 3; } else { fprintf(out, "%02x", data->data[i]); - column += 3; + column += 2; break; } - if (column > 76) { + if (column > 76 || (i % 16 == 15)) { secu_Newline(out); SECU_Indent(out, level); column = level*INDENT_MULT; } @@ -798,7 +798,14 @@ SECU_PrintInteger(FILE *out, SECItem *i, char *m, int level) { int iv; - if (i->len > 4) { + if (!i || !i->len || !i->data) { + SECU_Indent(out, level); + if (m) { + fprintf(out, "%s: (null)\n", m); + } else { + fprintf(out, "(null)\n"); + } + } else if (i->len > 4) { SECU_PrintAsHex(out, i, m, level); } else { iv = DER_GetInteger(i); @@ -1211,36 +1218,33 @@ secu_PrintSubjectPublicKeyInfo(FILE *out, PRArenaPool *arena, CERTSubjectPublicKeyInfo *i, char *msg, int level) { SECKEYPublicKey *pk; - int rv; SECU_Indent(out, level); fprintf(out, "%s:\n", msg); SECU_PrintAlgorithmID(out, &i->algorithm, "Public Key Algorithm", level+1); - pk = (SECKEYPublicKey*) PORT_ZAlloc(sizeof(SECKEYPublicKey)); - if (!pk) - return PORT_GetError(); - - DER_ConvertBitString(&i->subjectPublicKey); - switch(SECOID_FindOIDTag(&i->algorithm.algorithm)) { - case SEC_OID_PKCS1_RSA_ENCRYPTION: - rv = SEC_ASN1DecodeItem(arena, pk, - SEC_ASN1_GET(SECKEY_RSAPublicKeyTemplate), - &i->subjectPublicKey); - if (rv) - return rv; - secu_PrintRSAPublicKey(out, pk, "RSA Public Key", level +1); - break; - case SEC_OID_ANSIX9_DSA_SIGNATURE: - rv = SEC_ASN1DecodeItem(arena, pk, - SEC_ASN1_GET(SECKEY_DSAPublicKeyTemplate), - &i->subjectPublicKey); - if (rv) - return rv; - secu_PrintDSAPublicKey(out, pk, "DSA Public Key", level +1); - break; - default: - fprintf(out, "bad SPKI algorithm type\n"); - return 0; + pk = SECKEY_ExtractPublicKey(i); + if (pk) { + switch (pk->keyType) { + case rsaKey: + secu_PrintRSAPublicKey(out, pk, "RSA Public Key", level +1); + break; + + case dsaKey: + secu_PrintDSAPublicKey(out, pk, "DSA Public Key", level +1); + break; + + case dhKey: + case fortezzaKey: + case keaKey: + fprintf(out, "unable to format this SPKI algorithm type\n"); + break; + default: + fprintf(out, "unknown SPKI algorithm type\n"); + break; + } + PORT_FreeArena(pk->arena, PR_FALSE); + } else { + SECU_PrintError("Error", "Parsing public key"); } return 0; diff --git a/security/nss/cmd/selfserv/selfserv.c b/security/nss/cmd/selfserv/selfserv.c index ea0797073..0bfbde109 100644 --- a/security/nss/cmd/selfserv/selfserv.c +++ b/security/nss/cmd/selfserv/selfserv.c @@ -1705,7 +1705,13 @@ main(int argc, char **argv) free(nickName); free(passwd); - NSS_Shutdown(); + SSL_ShutdownServerSessionIDCache(); + + if (NSS_Shutdown() != SECSuccess) { + SECU_PrintError(progName, "NSS_Shutdown"); + PR_Cleanup(); + exit(1); + } PR_Cleanup(); printf("selfserv: normal termination\n"); return 0; diff --git a/security/nss/lib/dev/dev.h b/security/nss/lib/dev/dev.h index 5c8d9245a..eeed87246 100644 --- a/security/nss/lib/dev/dev.h +++ b/security/nss/lib/dev/dev.h @@ -323,6 +323,18 @@ nssSlot_Logout nssSession *sessionOpt ); +NSS_EXTERN void +nssSlot_EnterMonitor +( + NSSSlot *slot +); + +NSS_EXTERN void +nssSlot_ExitMonitor +( + NSSSlot *slot +); + #define NSSSLOT_ASK_PASSWORD_FIRST_TIME -1 #define NSSSLOT_ASK_PASSWORD_EVERY_TIME 0 NSS_EXTERN void diff --git a/security/nss/lib/dev/devslot.c b/security/nss/lib/dev/devslot.c index 81cd512d5..ca26a74ef 100644 --- a/security/nss/lib/dev/devslot.c +++ b/security/nss/lib/dev/devslot.c @@ -76,6 +76,7 @@ struct NSSSlotStr CK_FLAGS ckFlags; /* from CK_SLOT_INFO.flags */ struct nssSlotAuthInfoStr authInfo; PRIntervalTime lastTokenPing; + PZLock *lock; #ifdef NSS_3_4_CODE PK11SlotInfo *pk11slot; #endif @@ -151,6 +152,9 @@ nssSlot_Create if (!rvSlot->base.lock) { goto loser; } + if (!nssModule_IsThreadSafe(parent)) { + rvSlot->lock = nssModule_GetLock(parent); + } rvSlot->module = parent; /* refs go from module to slots */ rvSlot->slotID = slotID; rvSlot->ckFlags = slotInfo.flags; @@ -190,6 +194,22 @@ nssSlot_Destroy return PR_SUCCESS; } +void +nssSlot_EnterMonitor(NSSSlot *slot) +{ + if (slot->lock) { + PZ_Lock(slot->lock); + } +} + +void +nssSlot_ExitMonitor(NSSSlot *slot) +{ + if (slot->lock) { + PZ_Unlock(slot->lock); + } +} + NSS_IMPLEMENT void NSSSlot_Destroy ( @@ -274,7 +294,9 @@ nssSlot_IsTokenPresent if (!epv) { return PR_FALSE; } + nssSlot_EnterMonitor(slot); ckrv = CKAPI(epv)->C_GetSlotInfo(slot->slotID, &slotInfo); + nssSlot_ExitMonitor(slot); if (ckrv != CKR_OK) { slot->token->base.name[0] = 0; /* XXX */ return PR_FALSE; @@ -772,9 +794,9 @@ nssSlot_CreateSession if (!rvSession) { return (nssSession *)NULL; } - if (!nssModule_IsThreadSafe(slot->module)) { - /* If the parent module is not threadsafe, create lock to manage - * session within threads. + if (nssModule_IsThreadSafe(slot->module)) { + /* If the parent module is threadsafe, + * create lock to protect just this session. */ rvSession->lock = PZ_NewLock(nssILockOther); if (!rvSession->lock) { @@ -785,7 +807,12 @@ nssSlot_CreateSession } return (nssSession *)NULL; } + rvSession->ownLock = PR_TRUE; + } else { + rvSession->lock = slot->lock; + rvSession->ownLock = PR_FALSE; } + rvSession->handle = handle; rvSession->slot = slot; rvSession->isRW = readWrite; @@ -802,7 +829,7 @@ nssSession_Destroy if (s) { void *epv = s->slot->epv; ckrv = CKAPI(epv)->C_CloseSession(s->handle); - if (s->lock) { + if (s->ownLock && s->lock) { PZ_DestroyLock(s->lock); } nss_ZFreeIf(s); diff --git a/security/nss/lib/dev/devt.h b/security/nss/lib/dev/devt.h index 10a7978c3..002f31144 100644 --- a/security/nss/lib/dev/devt.h +++ b/security/nss/lib/dev/devt.h @@ -124,6 +124,7 @@ struct NSSSlotStr CK_FLAGS ckFlags; /* from CK_SLOT_INFO.flags */ struct nssSlotAuthInfoStr authInfo; PRIntervalTime lastTokenPing; + PZLock *lock; #ifdef NSS_3_4_CODE void *epv; PK11SlotInfo *pk11slot; @@ -136,6 +137,7 @@ struct nssSessionStr CK_SESSION_HANDLE handle; NSSSlot *slot; PRBool isRW; + PRBool ownLock; }; typedef enum { diff --git a/security/nss/lib/nss/nss.h b/security/nss/lib/nss/nss.h index aad157f66..06880da37 100644 --- a/security/nss/lib/nss/nss.h +++ b/security/nss/lib/nss/nss.h @@ -49,11 +49,11 @@ SEC_BEGIN_PROTOS * The format of the version string should be * "<major version>.<minor version>[.<patch level>] [<Beta>]" */ -#define NSS_VERSION "3.7.3 Beta" +#define NSS_VERSION "3.7.5" #define NSS_VMAJOR 3 #define NSS_VMINOR 7 -#define NSS_VPATCH 3 -#define NSS_BETA PR_TRUE +#define NSS_VPATCH 5 +#define NSS_BETA PR_FALSE /* diff --git a/security/nss/lib/pk11wrap/dev3hack.c b/security/nss/lib/pk11wrap/dev3hack.c index 3f704436d..2c7ee38f2 100644 --- a/security/nss/lib/pk11wrap/dev3hack.c +++ b/security/nss/lib/pk11wrap/dev3hack.c @@ -67,6 +67,7 @@ nssSession_ImportNSS3Session(NSSArena *arenaOpt, rvSession = nss_ZNEW(arenaOpt, nssSession); rvSession->handle = session; rvSession->lock = lock; + rvSession->ownLock = PR_FALSE; rvSession->isRW = rw; return rvSession; } @@ -92,6 +93,23 @@ nssSlot_CreateSession } rvSession->isRW = PR_TRUE; rvSession->slot = slot; + /* + * The session doesn't need its own lock. Here's why. + * 1. If we are reusing the default RW session of the slot, + * the slot lock is already locked to protect the session. + * 2. If the module is not thread safe, the slot (or rather + * module) lock is already locked. + * 3. If the module is thread safe and we are using a new + * session, no higher-level lock has been locked and we + * would need a lock for the new session. However, the + * NSS_3_4_CODE usage of the session is that it is always + * used and destroyed within the same function and never + * shared with another thread. + * So the session is either already protected by another + * lock or only used by one thread. + */ + rvSession->lock = NULL; + rvSession->ownLock = PR_FALSE; return rvSession; } else { return NULL; @@ -136,6 +154,7 @@ nssSlot_CreateFromPK11SlotInfo(NSSTrustDomain *td, PK11SlotInfo *nss3slot) rvSlot->slotID = nss3slot->slotID; /* Grab the slot name from the PKCS#11 fixed-length buffer */ rvSlot->base.name = nssUTF8_Duplicate(nss3slot->slot_name,td->arena); + rvSlot->lock = (nss3slot->isThreadSafe) ? NULL : nss3slot->sessionLock; return rvSlot; } diff --git a/security/nss/lib/pk11wrap/pk11func.h b/security/nss/lib/pk11wrap/pk11func.h index f80d99bda..422d809fc 100644 --- a/security/nss/lib/pk11wrap/pk11func.h +++ b/security/nss/lib/pk11wrap/pk11func.h @@ -83,7 +83,7 @@ CK_SESSION_HANDLE PK11_GetRWSession(PK11SlotInfo *slot); void PK11_RestoreROSession(PK11SlotInfo *slot,CK_SESSION_HANDLE rwsession); PRBool PK11_RWSessionHasLock(PK11SlotInfo *slot, CK_SESSION_HANDLE session_handle); -PK11SlotInfo *PK11_NewSlotInfo(void); +PK11SlotInfo *PK11_NewSlotInfo(SECMODModule *mod); SECStatus PK11_Logout(PK11SlotInfo *slot); void PK11_LogoutAll(void); void PK11_EnterSlotMonitor(PK11SlotInfo *); diff --git a/security/nss/lib/pk11wrap/pk11load.c b/security/nss/lib/pk11wrap/pk11load.c index f9ff7d506..4da327680 100644 --- a/security/nss/lib/pk11wrap/pk11load.c +++ b/security/nss/lib/pk11wrap/pk11load.c @@ -271,7 +271,7 @@ SECMOD_LoadPKCS11Module(SECMODModule *mod) { /* Initialize each slot */ for (i=0; i < (int)slotCount; i++) { - mod->slots[i] = PK11_NewSlotInfo(); + mod->slots[i] = PK11_NewSlotInfo(mod); PK11_InitSlot(mod,slotIDs[i],mod->slots[i]); /* look down the slot info table */ PK11_LoadSlotList(mod->slots[i],mod->slotInfo,mod->slotInfoCount); diff --git a/security/nss/lib/pk11wrap/pk11slot.c b/security/nss/lib/pk11wrap/pk11slot.c index 56fe6ac49..fc4ba1a05 100644 --- a/security/nss/lib/pk11wrap/pk11slot.c +++ b/security/nss/lib/pk11wrap/pk11slot.c @@ -378,7 +378,7 @@ PK11_FindSlotElement(PK11SlotList *list,PK11SlotInfo *slot) * Create a new slot structure */ PK11SlotInfo * -PK11_NewSlotInfo(void) +PK11_NewSlotInfo(SECMODModule *mod) { PK11SlotInfo *slot; @@ -391,7 +391,8 @@ PK11_NewSlotInfo(void) PORT_Free(slot); return slot; } - slot->sessionLock = PZ_NewLock(nssILockSession); + slot->sessionLock = mod->isThreadSafe ? + PZ_NewLock(nssILockSession) : (PZLock *)mod->refLock; if (slot->sessionLock == NULL) { PZ_DestroyLock(slot->refLock); PORT_Free(slot); @@ -399,7 +400,9 @@ PK11_NewSlotInfo(void) } slot->freeListLock = PZ_NewLock(nssILockFreelist); if (slot->freeListLock == NULL) { - PZ_DestroyLock(slot->sessionLock); + if (mod->isThreadSafe) { + PZ_DestroyLock(slot->sessionLock); + } PZ_DestroyLock(slot->refLock); PORT_Free(slot); return slot; @@ -478,26 +481,26 @@ PK11_DestroySlot(PK11SlotInfo *slot) if (slot->mechanismList) { PORT_Free(slot->mechanismList); } - - /* finally Tell our parent module that we've gone away so it can unload */ - if (slot->module) { - SECMOD_SlotDestroyModule(slot->module,PR_TRUE); - } #ifdef PKCS11_USE_THREADS if (slot->refLock) { PZ_DestroyLock(slot->refLock); slot->refLock = NULL; } - if (slot->sessionLock) { + if (slot->isThreadSafe && slot->sessionLock) { PZ_DestroyLock(slot->sessionLock); - slot->sessionLock = NULL; } + slot->sessionLock = NULL; if (slot->freeListLock) { PZ_DestroyLock(slot->freeListLock); slot->freeListLock = NULL; } #endif + /* finally Tell our parent module that we've gone away so it can unload */ + if (slot->module) { + SECMOD_SlotDestroyModule(slot->module,PR_TRUE); + } + /* ok, well not quit finally... now we free the memory */ PORT_Free(slot); } diff --git a/security/nss/lib/pk11wrap/pk11util.c b/security/nss/lib/pk11wrap/pk11util.c index a97d5fa9d..01dfd18d8 100644 --- a/security/nss/lib/pk11wrap/pk11util.c +++ b/security/nss/lib/pk11wrap/pk11util.c @@ -112,7 +112,11 @@ SECMOD_Shutdown() { PORT_Assert(secmod_PrivateModuleCount == 0); } #endif - return (secmod_PrivateModuleCount == 0) ? SECSuccess : SECFailure; + if (secmod_PrivateModuleCount) { + PORT_SetError(SEC_ERROR_BUSY); + return SECFailure; + } + return SECSuccess; } diff --git a/security/nss/lib/smime/cmsdecode.c b/security/nss/lib/smime/cmsdecode.c index 906fbaa25..8ba2b33dd 100644 --- a/security/nss/lib/smime/cmsdecode.c +++ b/security/nss/lib/smime/cmsdecode.c @@ -59,6 +59,13 @@ struct NSSCMSDecoderContextStr { void * cb_arg; }; +struct NSSCMSDecoderDataStr { + SECItem data; /* must be first */ + unsigned int totalBufferSize; +}; + +typedef struct NSSCMSDecoderDataStr NSSCMSDecoderData; + static void nss_cms_decoder_update_filter (void *arg, const char *data, unsigned long len, int depth, SEC_ASN1EncodingPart data_kind); static SECStatus nss_cms_before_data(NSSCMSDecoderContext *p7dcx); @@ -66,9 +73,26 @@ static SECStatus nss_cms_after_data(NSSCMSDecoderContext *p7dcx); static SECStatus nss_cms_after_end(NSSCMSDecoderContext *p7dcx); static void nss_cms_decoder_work_data(NSSCMSDecoderContext *p7dcx, const unsigned char *data, unsigned long len, PRBool final); +static NSSCMSDecoderData *nss_cms_create_decoder_data(PRArenaPool *poolp); extern const SEC_ASN1Template NSSCMSMessageTemplate[]; +static NSSCMSDecoderData * +nss_cms_create_decoder_data(PRArenaPool *poolp) +{ + NSSCMSDecoderData *decoderData = NULL; + + decoderData = (NSSCMSDecoderData *) + PORT_ArenaAlloc(poolp,sizeof(NSSCMSDecoderData)); + if (!decoderData) { + return NULL; + } + decoderData->data.data = NULL; + decoderData->data.len = 0; + decoderData->totalBufferSize = 0; + return decoderData; +} + /* * nss_cms_decoder_notify - * this is the driver of the decoding process. It gets called by the ASN.1 @@ -250,8 +274,8 @@ nss_cms_before_data(NSSCMSDecoderContext *p7dcx) childtype = NSS_CMSContentInfo_GetContentTypeTag(cinfo); if (childtype == SEC_OID_PKCS7_DATA) { - cinfo->content.data = SECITEM_AllocItem(poolp, NULL, 0); - if (cinfo->content.data == NULL) + cinfo->content.pointer = (void *) nss_cms_create_decoder_data(poolp); + if (cinfo->content.pointer == NULL) /* set memory error */ return SECFailure; @@ -414,7 +438,6 @@ nss_cms_decoder_work_data(NSSCMSDecoderContext *p7dcx, unsigned char *dest; unsigned int offset; SECStatus rv; - SECItem *storage; /* * We should really have data to process, or we should be trying @@ -510,27 +533,30 @@ nss_cms_decoder_work_data(NSSCMSDecoderContext *p7dcx, if (NSS_CMSContentInfo_GetContentTypeTag(cinfo) == SEC_OID_PKCS7_DATA) { /* store it in "inner" data item as well */ /* find the DATA item in the encapsulated cinfo and store it there */ - storage = cinfo->content.data; - - offset = storage->len; - if (storage->len == 0) { - dest = (unsigned char *)PORT_ArenaAlloc(p7dcx->cmsg->poolp, len); - } else { - dest = (unsigned char *)PORT_ArenaGrow(p7dcx->cmsg->poolp, - storage->data, - storage->len, - storage->len + len); - } - if (dest == NULL) { - p7dcx->error = SEC_ERROR_NO_MEMORY; - goto loser; - } + NSSCMSDecoderData *decoderData = + (NSSCMSDecoderData *)cinfo->content.pointer; + SECItem *dataItem = &decoderData->data; + + offset = dataItem->len; + if (dataItem->len+len > decoderData->totalBufferSize) { + int needLen = (dataItem->len+len) * 2; + dest = (unsigned char *) + PORT_ArenaAlloc(p7dcx->cmsg->poolp, needLen); + if (dest == NULL) { + p7dcx->error = SEC_ERROR_NO_MEMORY; + goto loser; + } - storage->data = dest; - storage->len += len; + if (dataItem->len) { + PORT_Memcpy(dest, dataItem->data, dataItem->len); + } + decoderData->totalBufferSize = needLen; + dataItem->data = dest; + } /* copy it in */ - PORT_Memcpy(storage->data + offset, data, len); + PORT_Memcpy(dataItem->data + offset, data, len); + dataItem->len += len; } done: diff --git a/security/nss/lib/ssl/ssl.def b/security/nss/lib/ssl/ssl.def index 7833ae741..33083caea 100644 --- a/security/nss/lib/ssl/ssl.def +++ b/security/nss/lib/ssl/ssl.def @@ -115,3 +115,9 @@ SSL_SetMaxServerCacheLocks; ;+ local: ;+*; ;+}; +;+NSS_3.7.4 { # NSS 3.7.4 release +;+ global: +SSL_ShutdownServerSessionIDCache; +;+ local: +;+*; +;+}; diff --git a/security/nss/lib/ssl/ssl.h b/security/nss/lib/ssl/ssl.h index 59b511f31..cbc5dcc6d 100644 --- a/security/nss/lib/ssl/ssl.h +++ b/security/nss/lib/ssl/ssl.h @@ -365,6 +365,11 @@ SSL_IMPORT SECItem *SSL_GetSessionID(PRFileDesc *fd); SSL_IMPORT void SSL_ClearSessionCache(void); /* +** Close the server's SSL session cache. +*/ +SSL_IMPORT SECStatus SSL_ShutdownServerSessionIDCache(void); + +/* ** Set peer information so we can correctly look up SSL session later. ** You only have to do this if you're tunneling through a proxy. */ diff --git a/security/nss/lib/ssl/ssl3con.c b/security/nss/lib/ssl/ssl3con.c index 82068cb56..92375ada7 100644 --- a/security/nss/lib/ssl/ssl3con.c +++ b/security/nss/lib/ssl/ssl3con.c @@ -3024,6 +3024,33 @@ typedef struct { PK11SymKey * symWrapKey[kt_kea_size]; } ssl3SymWrapKey; +static PZLock * symWrapKeysLock; +static ssl3SymWrapKey symWrapKeys[SSL_NUM_WRAP_MECHS]; + +SECStatus +SSL3_ShutdownServerCache(void) +{ + int i, j; + + if (!symWrapKeysLock) + return SECSuccess; /* was never initialized */ + PZ_Lock(symWrapKeysLock); + /* get rid of all symWrapKeys */ + for (i = 0; i < SSL_NUM_WRAP_MECHS; ++i) { + for (j = 0; j < kt_kea_size; ++j) { + PK11SymKey ** pSymWrapKey; + pSymWrapKey = &symWrapKeys[i].symWrapKey[j]; + if (*pSymWrapKey) { + PK11_FreeSymKey(*pSymWrapKey); + *pSymWrapKey = NULL; + } + } + } + + PZ_Unlock(symWrapKeysLock); + return SECSuccess; +} + /* Try to get wrapping key for mechanism from in-memory array. * If that fails, look for one on disk. * If that fails, generate a new one, put the new one on disk, @@ -3048,9 +3075,6 @@ getWrappingKey( sslSocket * ss, SECItem wrappedKey; SSLWrappedSymWrappingKey wswk; - static PZLock * symWrapKeysLock; - static ssl3SymWrapKey symWrapKeys[SSL_NUM_WRAP_MECHS]; - svrPrivKey = ss->serverCerts[exchKeyType].serverKey; PORT_Assert(svrPrivKey != NULL); if (!svrPrivKey) { diff --git a/security/nss/lib/ssl/sslimpl.h b/security/nss/lib/ssl/sslimpl.h index b99bf1d21..1eb968018 100644 --- a/security/nss/lib/ssl/sslimpl.h +++ b/security/nss/lib/ssl/sslimpl.h @@ -1248,6 +1248,9 @@ ssl_GetWrappingKey( PRInt32 symWrapMechIndex, extern PRBool ssl_SetWrappingKey(SSLWrappedSymWrappingKey *wswk); +/* get rid of the symmetric wrapping key references. */ +extern SECStatus SSL3_ShutdownServerCache(void); + /********************** misc calls *********************/ extern int ssl_MapLowLevelError(int hiLevelError); diff --git a/security/nss/lib/ssl/sslsnce.c b/security/nss/lib/ssl/sslsnce.c index 4d583b3d9..7143896e3 100644 --- a/security/nss/lib/ssl/sslsnce.c +++ b/security/nss/lib/ssl/sslsnce.c @@ -1139,6 +1139,22 @@ SSL_ConfigServerSessionIDCache( int maxCacheEntries, maxCacheEntries, ssl2_timeout, ssl3_timeout, directory); } +SECStatus +SSL_ShutdownServerSessionIDCacheInstance(cacheDesc *cache) +{ + /* if single process, close down, clean up. + ** if multi-process, TBD. + */ + return SECSuccess; +} + +SECStatus +SSL_ShutdownServerSessionIDCache(void) +{ + SSL3_ShutdownServerCache(); + return SSL_ShutdownServerSessionIDCacheInstance(&globalCache); +} + /* Use this function, instead of SSL_ConfigServerSessionIDCache, * if the cache will be shared by multiple processes. */ diff --git a/security/nss/lib/util/secasn1d.c b/security/nss/lib/util/secasn1d.c index 890ddddba..4f3a8be1b 100644 --- a/security/nss/lib/util/secasn1d.c +++ b/security/nss/lib/util/secasn1d.c @@ -600,6 +600,32 @@ sec_asn1d_init_state_based_on_template (sec_asn1d_state *state) return state; } +static PRBool +sec_asn1d_parent_is_indefinite(sec_asn1d_state *state) +{ + for (state = state->parent; state; state = state->parent) { + sec_asn1d_parse_place place = state->place; + if (place != afterImplicit && + place != afterPointer && + place != afterInline && + place != afterSaveEncoding && + place != duringSaveEncoding && + place != duringChoice) { + + /* we've walked up the stack to a state that represents + ** the enclosing construct. Is it one of the types that + ** permits an unexpected EOC? + */ + int eoc_permitted = + (place == duringGroup || + place == duringConstructedString || + state->child->optional); + return (state->indefinite && eoc_permitted) ? PR_TRUE : PR_FALSE; + + } + } + return PR_FALSE; +} static unsigned long sec_asn1d_parse_identifier (sec_asn1d_state *state, @@ -628,15 +654,7 @@ sec_asn1d_parse_identifier (sec_asn1d_state *state, */ state->pending = 1; } else { - if (byte == 0 && state->parent != NULL && - (state->parent->indefinite || - ( - (state->parent->place == afterImplicit || - state->parent->place == afterPointer) - && state->parent->parent != NULL && state->parent->parent->indefinite - ) - ) - ) { + if (byte == 0 && sec_asn1d_parent_is_indefinite(state)) { /* * Our parent has indefinite-length encoding, and the * entire tag found is 0, so it seems that we have hit the @@ -2187,6 +2205,26 @@ sec_asn1d_during_choice unsigned char child_found_tag_modifiers = 0; unsigned long child_found_tag_number = 0; + state->consumed += child->consumed; + + if (child->endofcontents) { + /* This choice is probably the first item in a GROUP + ** (e.g. SET_OF) that was indefinite-length encoded. + ** We're actually at the end of that GROUP. + ** We should look up the stack to be sure that we find + ** a state with indefinite length encoding before we + ** find a state (like a SEQUENCE) that is definite. + */ + child->place = notInUse; + state->place = afterChoice; + state->endofcontents = PR_TRUE; /* propagate this up */ + if (sec_asn1d_parent_is_indefinite(state)) + return state; + PORT_SetError(SEC_ERROR_BAD_DER); + state->top->status = decodeError; + return NULL; + } + child->theTemplate++; if( 0 == child->theTemplate->kind ) { @@ -2196,8 +2234,6 @@ sec_asn1d_during_choice return (sec_asn1d_state *)NULL; } - state->consumed += child->consumed; - /* cargo'd from next_in_sequence innards */ if( state->pending ) { PORT_Assert(!state->indefinite); |