diff options
author | nelsonb%netscape.com <devnull@localhost> | 2000-09-12 22:43:41 +0000 |
---|---|---|
committer | nelsonb%netscape.com <devnull@localhost> | 2000-09-12 22:43:41 +0000 |
commit | cdb69f34c5d31833da9e62901342371c7a49a680 (patch) | |
tree | 9e2326b331bd6e9cc45a03c9eb8568c3aed4042a | |
parent | 33410214218e77af0e5cde14e35e48e0a4449fa2 (diff) | |
download | nss-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.h | 6 | ||||
-rw-r--r-- | security/nss/lib/certhigh/certhigh.c | 83 | ||||
-rw-r--r-- | security/nss/lib/ssl/ssl3con.c | 8 | ||||
-rw-r--r-- | security/nss/lib/ssl/sslerr.c | 2 | ||||
-rw-r--r-- | security/nss/lib/ssl/sslsecur.c | 5 | ||||
-rw-r--r-- | security/nss/lib/ssl/sslsnce.c | 6 | ||||
-rw-r--r-- | security/nss/lib/ssl/sslsock.c | 77 |
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; |