summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authornelsonb%netscape.com <devnull@localhost>2000-09-12 22:43:41 +0000
committernelsonb%netscape.com <devnull@localhost>2000-09-12 22:43:41 +0000
commitcdb69f34c5d31833da9e62901342371c7a49a680 (patch)
tree9e2326b331bd6e9cc45a03c9eb8568c3aed4042a
parent33410214218e77af0e5cde14e35e48e0a4449fa2 (diff)
downloadnss-hg-cdb69f34c5d31833da9e62901342371c7a49a680.tar.gz
Merge fixes for bugs 51425 51559 51913 and 52092 from trunk onto the
NSS_30_BRANCH.
-rw-r--r--security/nss/lib/certdb/cert.h6
-rw-r--r--security/nss/lib/certhigh/certhigh.c83
-rw-r--r--security/nss/lib/ssl/ssl3con.c8
-rw-r--r--security/nss/lib/ssl/sslerr.c2
-rw-r--r--security/nss/lib/ssl/sslsecur.c5
-rw-r--r--security/nss/lib/ssl/sslsnce.c6
-rw-r--r--security/nss/lib/ssl/sslsock.c77
7 files changed, 162 insertions, 25 deletions
diff --git a/security/nss/lib/certdb/cert.h b/security/nss/lib/certdb/cert.h
index a390af7f3..d77bcb5a4 100644
--- a/security/nss/lib/certdb/cert.h
+++ b/security/nss/lib/certdb/cert.h
@@ -902,6 +902,12 @@ extern CERTCertificateList *
CERT_CertChainFromCert(CERTCertificate *cert, SECCertUsage usage,
PRBool includeRoot);
+extern CERTCertificateList *
+CERT_CertListFromCert(CERTCertificate *cert);
+
+extern CERTCertificateList *
+CERT_DupCertList(CERTCertificateList * oldList);
+
extern void CERT_DestroyCertificateList(CERTCertificateList *list);
/* is cert a newer than cert b? */
diff --git a/security/nss/lib/certhigh/certhigh.c b/security/nss/lib/certhigh/certhigh.c
index c01de0b81..e24ad7553 100644
--- a/security/nss/lib/certhigh/certhigh.c
+++ b/security/nss/lib/certhigh/certhigh.c
@@ -980,10 +980,10 @@ CERT_CertChainFromCert(CERTCertificate *cert, SECCertUsage usage,
node->cert = NULL;
if (rv < 0) goto loser;
}
- if ( includeRoot ) {
- chain->len = len;
- } else {
+ if ( !includeRoot && len > 1) {
chain->len = len - 1;
+ } else {
+ chain->len = len;
}
chain->arena = arena;
@@ -1013,6 +1013,83 @@ loser:
return NULL;
}
+/* Builds a CERTCertificateList holding just one DER-encoded cert, namely
+** the one for the cert passed as an argument.
+*/
+CERTCertificateList *
+CERT_CertListFromCert(CERTCertificate *cert)
+{
+ CERTCertificateList *chain = NULL;
+ int rv;
+ PRArenaPool *arena;
+
+ /* arena for SecCertificateList */
+ arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
+ if (arena == NULL) goto no_memory;
+
+ /* build the CERTCertificateList */
+ chain = (CERTCertificateList *)PORT_ArenaAlloc(arena, sizeof(CERTCertificateList));
+ if (chain == NULL) goto no_memory;
+ chain->certs = (SECItem*)PORT_ArenaAlloc(arena, 1 * sizeof(SECItem));
+ if (chain->certs == NULL) goto no_memory;
+ rv = SECITEM_CopyItem(arena, chain->certs, &(cert->derCert));
+ if (rv < 0) goto loser;
+ chain->len = 1;
+ chain->arena = arena;
+
+ return chain;
+
+no_memory:
+ PORT_SetError(SEC_ERROR_NO_MEMORY);
+loser:
+ if (arena != NULL) {
+ PORT_FreeArena(arena, PR_FALSE);
+ }
+ return NULL;
+}
+
+CERTCertificateList *
+CERT_DupCertList(CERTCertificateList * oldList)
+{
+ CERTCertificateList *newList = NULL;
+ PRArenaPool *arena = NULL;
+ SECItem *newItem;
+ SECItem *oldItem;
+ int len = oldList->len;
+ int rv;
+
+ /* arena for SecCertificateList */
+ arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
+ if (arena == NULL)
+ goto no_memory;
+
+ /* now build the CERTCertificateList */
+ newList = PORT_ArenaNew(arena, CERTCertificateList);
+ if (newList == NULL)
+ goto no_memory;
+ newList->arena = arena;
+ newItem = (SECItem*)PORT_ArenaAlloc(arena, len * sizeof(SECItem));
+ if (newItem == NULL)
+ goto no_memory;
+ newList->certs = newItem;
+ newList->len = len;
+
+ for (oldItem = oldList->certs; len > 0; --len, ++newItem, ++oldItem) {
+ rv = SECITEM_CopyItem(arena, newItem, oldItem);
+ if (rv < 0)
+ goto loser;
+ }
+ return newList;
+
+no_memory:
+ PORT_SetError(SEC_ERROR_NO_MEMORY);
+loser:
+ if (arena != NULL) {
+ PORT_FreeArena(arena, PR_FALSE);
+ }
+ return NULL;
+}
+
void
CERT_DestroyCertificateList(CERTCertificateList *list)
{
diff --git a/security/nss/lib/ssl/ssl3con.c b/security/nss/lib/ssl/ssl3con.c
index 93d5b2773..c2fde0f22 100644
--- a/security/nss/lib/ssl/ssl3con.c
+++ b/security/nss/lib/ssl/ssl3con.c
@@ -845,6 +845,7 @@ static SECStatus
ssl3_SetupPendingCipherSpec(sslSocket *ss, ssl3State *ssl3)
{
ssl3CipherSpec * pwSpec;
+ ssl3CipherSpec * cwSpec;
ssl3CipherSuite suite = ssl3->hs.cipher_suite;
sslSecurityInfo * sec = ss->sec;
SSL3MACAlgorithm mac;
@@ -860,6 +861,13 @@ ssl3_SetupPendingCipherSpec(sslSocket *ss, ssl3State *ssl3)
pwSpec = ssl3->pwSpec;
PORT_Assert(pwSpec == ssl3->prSpec);
+ /* This hack provides maximal interoperability with SSL 3 servers. */
+ cwSpec = ss->ssl3->cwSpec;
+ if (cwSpec->mac_def->mac == mac_null) {
+ /* SSL records are not being MACed. */
+ cwSpec->version = ss->version;
+ }
+
pwSpec->version = ss->version;
isTLS = (PRBool)(pwSpec->version > SSL_LIBRARY_VERSION_3_0);
diff --git a/security/nss/lib/ssl/sslerr.c b/security/nss/lib/ssl/sslerr.c
index 5a2d27a3e..f3e57d44d 100644
--- a/security/nss/lib/ssl/sslerr.c
+++ b/security/nss/lib/ssl/sslerr.c
@@ -58,8 +58,10 @@ ssl_MapLowLevelError(int hiLevelError)
case SEC_ERROR_IO:
case SEC_ERROR_BAD_DATA:
case SEC_ERROR_LIBRARY_FAILURE:
+ case SEC_ERROR_EXTENSION_NOT_FOUND:
case SSL_ERROR_BAD_CLIENT:
case SSL_ERROR_BAD_SERVER:
+ case SSL_ERROR_SESSION_NOT_FOUND:
PORT_SetError(hiLevelError);
return hiLevelError;
diff --git a/security/nss/lib/ssl/sslsecur.c b/security/nss/lib/ssl/sslsecur.c
index 76b252064..14a5e830e 100644
--- a/security/nss/lib/ssl/sslsecur.c
+++ b/security/nss/lib/ssl/sslsecur.c
@@ -1181,6 +1181,11 @@ SSL_SetURL(PRFileDesc *fd, const char *url)
sslSocket * ss = ssl_FindSocket(fd);
int rv = SECSuccess;
+ if (!ss) {
+ SSL_DBG(("%d: SSL[%d]: bad socket in SSLSetURL",
+ SSL_GETPID(), fd));
+ return SECFailure;
+ }
ssl_Get1stHandshakeLock(ss);
ssl_GetSSL3HandshakeLock(ss);
diff --git a/security/nss/lib/ssl/sslsnce.c b/security/nss/lib/ssl/sslsnce.c
index bf58c954d..443cbe202 100644
--- a/security/nss/lib/ssl/sslsnce.c
+++ b/security/nss/lib/ssl/sslsnce.c
@@ -1214,10 +1214,15 @@ static void
ServerSessionIDUncache(sslSessionID *sid)
{
SIDCacheEntry sce;
+ PRErrorCode err;
int rv;
if (sid == NULL) return;
+ /* Uncaching a SID should never change the error code.
+ ** So save it here and restore it before exiting.
+ */
+ err = PR_GetError();
lock_cache();
if (sid->version < SSL_LIBRARY_VERSION_3_0) {
SSL_TRC(8, ("%d: SSL: UncacheMT: valid=%d addr=0x%08x time=%x "
@@ -1246,6 +1251,7 @@ ServerSessionIDUncache(sslSessionID *sid)
}
sid->cached = invalid_cache;
unlock_cache();
+ PORT_SetError(err);
}
static SECStatus
diff --git a/security/nss/lib/ssl/sslsock.c b/security/nss/lib/ssl/sslsock.c
index 2921e3b6c..b3387ca11 100644
--- a/security/nss/lib/ssl/sslsock.c
+++ b/security/nss/lib/ssl/sslsock.c
@@ -285,11 +285,10 @@ ssl_DupSocket(sslSocket *os)
int i;
for (i=kt_null; i < kt_kea_size; i++) {
- if (os->serverCert[i]) {
+ if (os->serverCert[i] && os->serverCertChain[i]) {
ss->serverCert[i] = CERT_DupCertificate(os->serverCert[i]);
- ss->serverCertChain[i] = CERT_CertChainFromCert
- (ss->serverCert[i], certUsageSSLServer,
- PR_TRUE);
+ ss->serverCertChain[i] = CERT_DupCertList(
+ os->serverCertChain[i]);
} else {
ss->serverCert[i] = NULL;
ss->serverCertChain[i] = NULL;
@@ -1610,7 +1609,7 @@ ssl_SendTo(PRFileDesc *fd, const void *buf, PRInt32 amount, PRIntn flags,
return SECFailure;
}
-static PRIOMethods ssl_methods = {
+static const PRIOMethods ssl_methods = {
PR_DESC_LAYERED,
ssl_Close, /* close */
ssl_Read, /* read */
@@ -1649,23 +1648,59 @@ static PRIOMethods ssl_methods = {
NULL /* reserved for future use */
};
+
+static PRIOMethods combined_methods;
+
static void
-ssl_SetupIOMethods(PRIOMethods *ssl_methods)
+ssl_SetupIOMethods(void)
{
- const PRIOMethods *default_methods;
+ PRIOMethods *new_methods = &combined_methods;
+ const PRIOMethods *nspr_methods = PR_GetDefaultIOMethods();
+ const PRIOMethods *my_methods = &ssl_methods;
+
+ *new_methods = *nspr_methods;
+
+ new_methods->file_type = my_methods->file_type;
+ new_methods->close = my_methods->close;
+ new_methods->read = my_methods->read;
+ new_methods->write = my_methods->write;
+ new_methods->available = my_methods->available;
+ new_methods->available64 = my_methods->available64;
+ new_methods->fsync = my_methods->fsync;
+ new_methods->seek = my_methods->seek;
+ new_methods->seek64 = my_methods->seek64;
+ new_methods->fileInfo = my_methods->fileInfo;
+ new_methods->fileInfo64 = my_methods->fileInfo64;
+ new_methods->writev = my_methods->writev;
+ new_methods->connect = my_methods->connect;
+ new_methods->accept = my_methods->accept;
+ new_methods->bind = my_methods->bind;
+ new_methods->listen = my_methods->listen;
+ new_methods->shutdown = my_methods->shutdown;
+ new_methods->recv = my_methods->recv;
+ new_methods->send = my_methods->send;
+ new_methods->recvfrom = my_methods->recvfrom;
+ new_methods->sendto = my_methods->sendto;
+ new_methods->poll = my_methods->poll;
+ new_methods->acceptread = my_methods->acceptread;
+ new_methods->transmitfile = my_methods->transmitfile;
+ new_methods->getsockname = my_methods->getsockname;
+ new_methods->getpeername = my_methods->getpeername;
+/* new_methods->getsocketoption = my_methods->getsocketoption; */
+/* new_methods->setsocketoption = my_methods->setsocketoption; */
+ new_methods->sendfile = my_methods->sendfile;
- default_methods = PR_GetDefaultIOMethods();
+}
- ssl_methods->reserved_fn_6 = default_methods->reserved_fn_6;
- ssl_methods->reserved_fn_5 = default_methods->reserved_fn_5;
- ssl_methods->getsocketoption = default_methods->getsocketoption;
- ssl_methods->setsocketoption = default_methods->setsocketoption;
- ssl_methods->reserved_fn_4 = default_methods->reserved_fn_4;
- ssl_methods->reserved_fn_3 = default_methods->reserved_fn_3;
- ssl_methods->reserved_fn_2 = default_methods->reserved_fn_2;
- ssl_methods->reserved_fn_1 = default_methods->reserved_fn_1;
- ssl_methods->reserved_fn_0 = default_methods->reserved_fn_0;
+static PRCallOnceType initIoLayerOnce;
+static PRStatus
+ssl_InitIOLayer(void)
+{
+ ssl_layer_id = PR_GetUniqueIdentity("SSL");
+ ssl_SetupIOMethods();
+ ssl_inited = PR_TRUE;
+ return PR_SUCCESS;
}
static PRStatus
@@ -1674,16 +1709,14 @@ ssl_PushIOLayer(sslSocket *ns, PRFileDesc *stack, PRDescIdentity id)
PRFileDesc *layer = NULL;
PRStatus status;
- if (ssl_inited != PR_TRUE) {
- ssl_layer_id = PR_GetUniqueIdentity("SSL");
- ssl_SetupIOMethods(&ssl_methods);
- ssl_inited = PR_TRUE;
+ if (!ssl_inited) {
+ PR_CallOnce(&initIoLayerOnce, &ssl_InitIOLayer);
}
if (ns == NULL)
goto loser;
- layer = PR_CreateIOLayerStub(ssl_layer_id, &ssl_methods);
+ layer = PR_CreateIOLayerStub(ssl_layer_id, &combined_methods);
if (layer == NULL)
goto loser;
layer->secret = (PRFilePrivate *)ns;