diff --git a/mozilla/security/nss/lib/ssl/ssl3con.c b/mozilla/security/nss/lib/ssl/ssl3con.c index 246c2d80a87..3951be4b9c4 100644 --- a/mozilla/security/nss/lib/ssl/ssl3con.c +++ b/mozilla/security/nss/lib/ssl/ssl3con.c @@ -32,7 +32,7 @@ * may use your version of this file under either the MPL or the * GPL. * - * $Id: ssl3con.c,v 1.5 2000-05-18 15:32:18 mcgreer%netscape.com Exp $ + * $Id: ssl3con.c,v 1.6 2000-05-24 03:35:23 nelsonb%netscape.com Exp $ */ #include "cert.h" @@ -1813,6 +1813,7 @@ ssl3_GenerateSessionKeys(sslSocket *ss, const PK11SymKey *pms) SECItem params; int keySize; CK_FLAGS keyFlags; + CK_VERSION pms_version; CK_SSL3_KEY_MAT_PARAMS key_material_params; CK_SSL3_KEY_MAT_OUT returnedKeys; CK_SSL3_MASTER_KEY_DERIVE_PARAMS master_params; @@ -1832,7 +1833,7 @@ ssl3_GenerateSessionKeys(sslSocket *ss, const PK11SymKey *pms) } if (pms || !pwSpec->master_secret) { - master_params.pVersion = NULL; + master_params.pVersion = &pms_version; master_params.RandomInfo.pClientRandom = cr; master_params.RandomInfo.ulClientRandomLen = SSL3_RANDOM_LENGTH; master_params.RandomInfo.pServerRandom = sr; @@ -1846,6 +1847,15 @@ ssl3_GenerateSessionKeys(sslSocket *ss, const PK11SymKey *pms) pwSpec->master_secret = PK11_DeriveWithFlags((PK11SymKey *)pms, master_derive, ¶ms, key_derive, CKA_DERIVE, 0, keyFlags); + if (pwSpec->master_secret != NULL && ss->detectRollBack) { + SSL3ProtocolVersion client_version; + client_version = pms_version.major << 8 | pms_version.minor; + if (client_version != ss->clientHelloVersion) { + /* Destroy it. Version roll-back detected. */ + PK11_FreeSymKey(pwSpec->master_secret); + pwSpec->master_secret = NULL; + } + } if (pwSpec->master_secret == NULL) { /* Generate a faux master secret in the same slot as the old one. */ PK11SlotInfo * slot = PK11_GetSlotFromKey((PK11SymKey *)pms); @@ -2556,7 +2566,8 @@ ssl3_SendClientHello(sslSocket *ss) return rv; /* err set by ssl3_AppendHandshake* */ } - rv = ssl3_AppendHandshakeNumber(ss, ss->version, 2); + ss->clientHelloVersion = ss->version; + rv = ssl3_AppendHandshakeNumber(ss, ss->clientHelloVersion, 2); if (rv != SECSuccess) { return rv; /* err set by ssl3_AppendHandshake* */ } @@ -4545,7 +4556,7 @@ ssl3_HandleClientHello(sslSocket *ss, SSL3Opaque *b, PRUint32 length) tmp = ssl3_ConsumeHandshakeNumber(ss, 2, &b, &length); if (tmp < 0) goto loser; /* malformed, alert already sent */ - version = (SSL3ProtocolVersion)tmp; + ss->clientHelloVersion = version = (SSL3ProtocolVersion)tmp; rv = ssl3_NegotiateVersion(ss, version); if (rv != SECSuccess) { /* We can't do the usual isTLS test here, because the negotiated @@ -4968,6 +4979,7 @@ ssl3_HandleV2ClientHello(sslSocket *ss, unsigned char *buffer, int length) suite_length = (buffer[3] << 8) | buffer[4]; sid_length = (buffer[5] << 8) | buffer[6]; rand_length = (buffer[7] << 8) | buffer[8]; + ss->clientHelloVersion = version; rv = ssl3_NegotiateVersion(ss, version); if (rv != SECSuccess) { @@ -5722,8 +5734,8 @@ ssl3_GenerateRSAPMS(sslSocket *ss, ssl3CipherSpec *spec, } /* Generate the pre-master secret ... */ - version.major = MSB(ss->version); - version.minor = LSB(ss->version); + version.major = MSB(ss->clientHelloVersion); + version.minor = LSB(ss->clientHelloVersion); param.data = (unsigned char *)&version; param.len = sizeof version; @@ -5777,7 +5789,10 @@ ssl3_HandleRSAClientKeyExchange(sslSocket *ss, } } /* - * decrypt out of the incoming buffer + * decrypt pms out of the incoming buffer + * Note: CKM_SSL3_PRE_MASTER_KEY_GEN is NOT the mechanism used to do + * the unwrap. Rather, it is the mechanism with which the unwrapped + * pms will be used. */ pms = PK11_PubUnwrapSymKey(serverKey, &enc_pms, CKM_SSL3_PRE_MASTER_KEY_GEN, CKA_DERIVE, 0); diff --git a/mozilla/security/nss/lib/ssl/sslcon.c b/mozilla/security/nss/lib/ssl/sslcon.c index 6a9cc564fff..4cc859e62c5 100644 --- a/mozilla/security/nss/lib/ssl/sslcon.c +++ b/mozilla/security/nss/lib/ssl/sslcon.c @@ -32,7 +32,7 @@ * may use your version of this file under either the MPL or the * GPL. * - * $Id: sslcon.c,v 1.1 2000-03-31 19:33:44 relyea%netscape.com Exp $ + * $Id: sslcon.c,v 1.2 2000-05-24 03:35:23 nelsonb%netscape.com Exp $ */ #include "cert.h" @@ -3075,16 +3075,15 @@ invalid: cp = msg = ci->sendBuf.buf; msg[0] = SSL_MT_CLIENT_HELLO; if ( ss->enableTLS ) { - msg[1] = MSB(SSL_LIBRARY_VERSION_3_1_TLS); - msg[2] = LSB(SSL_LIBRARY_VERSION_3_1_TLS); + ss->clientHelloVersion = SSL_LIBRARY_VERSION_3_1_TLS; } else if ( ss->enableSSL3 ) { - msg[1] = MSB(SSL_LIBRARY_VERSION_3_0); - msg[2] = LSB(SSL_LIBRARY_VERSION_3_0); + ss->clientHelloVersion = SSL_LIBRARY_VERSION_3_0; } else { - msg[1] = MSB(SSL_LIBRARY_VERSION_2); - msg[2] = LSB(SSL_LIBRARY_VERSION_2); + ss->clientHelloVersion = SSL_LIBRARY_VERSION_2; } + msg[1] = MSB(ss->clientHelloVersion); + msg[2] = LSB(ss->clientHelloVersion); msg[3] = MSB(localCipherSize); msg[4] = LSB(localCipherSize); msg[5] = MSB(sidLen); diff --git a/mozilla/security/nss/lib/ssl/sslimpl.h b/mozilla/security/nss/lib/ssl/sslimpl.h index 77f56616aa7..4454ed0a602 100644 --- a/mozilla/security/nss/lib/ssl/sslimpl.h +++ b/mozilla/security/nss/lib/ssl/sslimpl.h @@ -33,7 +33,7 @@ * may use your version of this file under either the MPL or the * GPL. * - * $Id: sslimpl.h,v 1.2 2000-05-12 18:43:28 dougt%netscape.com Exp $ + * $Id: sslimpl.h,v 1.3 2000-05-24 03:35:23 nelsonb%netscape.com Exp $ */ #ifndef __sslimpl_h_ @@ -222,6 +222,22 @@ typedef struct { #define ssl_V3_SUITES_IMPLEMENTED 13 +typedef struct sslOptionsStr { + unsigned int useSecurity : 1; /* 1 */ + unsigned int useSocks : 1; /* 2 */ + unsigned int requestCertificate : 1; /* 3 */ + unsigned int requireCertificate : 2; /* 4-5 */ + unsigned int handshakeAsClient : 1; /* 6 */ + unsigned int handshakeAsServer : 1; /* 7 */ + unsigned int enableSSL2 : 1; /* 8 */ + unsigned int enableSSL3 : 1; /* 9 */ + unsigned int enableTLS : 1; /* 10 */ + unsigned int noCache : 1; /* 11 */ + unsigned int fdx : 1; /* 12 */ + unsigned int v2CompatibleHello : 1; /* 13 */ + unsigned int detectRollBack : 1; /* 14 */ +} sslOptions; + /* ** SSL Socket struct ** @@ -249,11 +265,13 @@ struct sslSocketStr { unsigned int noCache : 1; unsigned int fdx : 1; /* simultaneous read/write threads */ unsigned int v2CompatibleHello : 1; /* Send v3+ client hello in v2 format */ + unsigned int detectRollBack : 1; /* Detect rollback to SSL v3 */ unsigned int connected : 1; /* initial handshake is complete. */ unsigned int recvdCloseNotify : 1; /* received SSL EOF. */ /* version of the protocol to use */ SSL3ProtocolVersion version; + SSL3ProtocolVersion clientHelloVersion; /* version sent in client hello. */ /* Non-zero if socks is enabled */ sslSocksInfo * socks; diff --git a/mozilla/security/nss/lib/ssl/sslsock.c b/mozilla/security/nss/lib/ssl/sslsock.c index c9c27958f91..8cd4d9ebb59 100644 --- a/mozilla/security/nss/lib/ssl/sslsock.c +++ b/mozilla/security/nss/lib/ssl/sslsock.c @@ -34,7 +34,7 @@ * may use your version of this file under either the MPL or the * GPL. * - * $Id: sslsock.c,v 1.1 2000-03-31 19:37:07 relyea%netscape.com Exp $ + * $Id: sslsock.c,v 1.2 2000-05-24 03:35:23 nelsonb%netscape.com Exp $ */ #include "seccomon.h" #include "cert.h" @@ -145,20 +145,7 @@ sslSocketOps ssl_secure_socks_ops = { /* Both SSL and Socks. */ /* ** default settings for socket enables */ -static struct { - unsigned int useSecurity : 1; - unsigned int useSocks : 1; - unsigned int requestCertificate : 1; - unsigned int requireCertificate : 2; - unsigned int handshakeAsClient : 1; - unsigned int handshakeAsServer : 1; - unsigned int enableSSL2 : 1; - unsigned int enableSSL3 : 1; - unsigned int enableTLS : 1; - unsigned int noCache : 1; - unsigned int fdx : 1; - unsigned int v2CompatibleHello : 1; -} ssl_defaults = { +static sslOptions ssl_defaults = { PR_TRUE, /* useSecurity */ PR_FALSE, /* useSocks */ PR_FALSE, /* requestCertificate */ @@ -167,10 +154,11 @@ static struct { PR_FALSE, /* handshakeAsServer */ PR_TRUE, /* enableSSL2 */ PR_TRUE, /* enableSSL3 */ - PR_FALSE, /* enableTLS */ + PR_TRUE, /* enableTLS */ /* now defaults to on in NSS 3.0 */ PR_FALSE, /* noCache */ PR_FALSE, /* fdx */ PR_TRUE, /* v2CompatibleHello */ + PR_TRUE, /* detectRollBack */ }; sslSessionIDLookupFunc ssl_sid_lookup; @@ -260,6 +248,7 @@ ssl_DupSocket(sslSocket *os) ss->noCache = os->noCache; ss->fdx = os->fdx; ss->v2CompatibleHello = os->v2CompatibleHello; + ss->detectRollBack = os->detectRollBack; ss->peerID = !os->peerID ? NULL : PORT_Strdup(os->peerID); ss->url = !os->url ? NULL : PORT_Strdup(os->url); @@ -596,6 +585,10 @@ SSL_OptionSet(PRFileDesc *fd, PRInt32 which, PRBool on) } break; + case SSL_ROLLBACK_DETECTION: + ss->detectRollBack = on; + break; + default: PORT_SetError(SEC_ERROR_INVALID_ARGS); rv = SECFailure; @@ -641,6 +634,7 @@ SSL_OptionGet(PRFileDesc *fd, PRInt32 which, PRBool *pOn) case SSL_NO_CACHE: on = ss->noCache; break; case SSL_ENABLE_FDX: on = ss->fdx; break; case SSL_V2_COMPATIBLE_HELLO: on = ss->v2CompatibleHello; break; + case SSL_ROLLBACK_DETECTION: on = ss->detectRollBack; break; default: PORT_SetError(SEC_ERROR_INVALID_ARGS); @@ -678,6 +672,7 @@ SSL_OptionGetDefault(PRInt32 which, PRBool *pOn) case SSL_NO_CACHE: on = ssl_defaults.noCache; break; case SSL_ENABLE_FDX: on = ssl_defaults.fdx; break; case SSL_V2_COMPATIBLE_HELLO: on = ssl_defaults.v2CompatibleHello; break; + case SSL_ROLLBACK_DETECTION: on = ssl_defaults.detectRollBack; break; default: PORT_SetError(SEC_ERROR_INVALID_ARGS); @@ -760,6 +755,10 @@ SSL_OptionSetDefault(PRInt32 which, PRBool on) } break; + case SSL_ROLLBACK_DETECTION: + ssl_defaults.detectRollBack = on; + break; + default: PORT_SetError(SEC_ERROR_INVALID_ARGS); return SECFailure; @@ -1769,6 +1768,7 @@ ssl_NewSocket(void) ss->enableTLS = ssl_defaults.enableTLS ; ss->fdx = ssl_defaults.fdx; ss->v2CompatibleHello = ssl_defaults.v2CompatibleHello; + ss->detectRollBack = ssl_defaults.detectRollBack; ss->peer = 0; ss->port = 0; ss->noCache = ssl_defaults.noCache;