summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorcvs2hg <devnull@localhost>2003-05-19 17:27:14 +0000
committercvs2hg <devnull@localhost>2003-05-19 17:27:14 +0000
commitf41bf619d6fc462202ac5598cccb7012a8aa9212 (patch)
tree7866a33c6072940e5db3cd3ea349e82038b00add
parent014cc87d40b6e622cd106e8323a5d3caafa613f1 (diff)
downloadnss-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.c64
-rw-r--r--security/nss/cmd/selfserv/selfserv.c8
-rw-r--r--security/nss/lib/dev/dev.h12
-rw-r--r--security/nss/lib/dev/devslot.c35
-rw-r--r--security/nss/lib/dev/devt.h2
-rw-r--r--security/nss/lib/nss/nss.h6
-rw-r--r--security/nss/lib/pk11wrap/dev3hack.c19
-rw-r--r--security/nss/lib/pk11wrap/pk11func.h2
-rw-r--r--security/nss/lib/pk11wrap/pk11load.c2
-rw-r--r--security/nss/lib/pk11wrap/pk11slot.c23
-rw-r--r--security/nss/lib/pk11wrap/pk11util.c6
-rw-r--r--security/nss/lib/smime/cmsdecode.c68
-rw-r--r--security/nss/lib/ssl/ssl.def6
-rw-r--r--security/nss/lib/ssl/ssl.h5
-rw-r--r--security/nss/lib/ssl/ssl3con.c30
-rw-r--r--security/nss/lib/ssl/sslimpl.h3
-rw-r--r--security/nss/lib/ssl/sslsnce.c16
-rw-r--r--security/nss/lib/util/secasn1d.c58
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);