Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(118)

Unified Diff: net/third_party/nss/ssl/ssl3con.c

Issue 11275240: Update net/third_party/nss/ssl to NSS 3.14. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: Upload before commit Created 8 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « net/third_party/nss/ssl/ssl.rc ('k') | net/third_party/nss/ssl/ssl3ecc.c » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: net/third_party/nss/ssl/ssl3con.c
===================================================================
--- net/third_party/nss/ssl/ssl3con.c (revision 166942)
+++ net/third_party/nss/ssl/ssl3con.c (working copy)
@@ -2,45 +2,10 @@
/*
* SSL3 Protocol
*
- * ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is the Netscape security libraries.
- *
- * The Initial Developer of the Original Code is
- * Netscape Communications Corporation.
- * Portions created by the Initial Developer are Copyright (C) 1994-2000
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- * Dr Stephen Henson <stephen.henson@gemplus.com>
- * Dr Vipul Gupta <vipul.gupta@sun.com> and
- * Douglas Stebila <douglas@stebila.ca>, Sun Microsystems Laboratories
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either the GNU General Public License Version 2 or later (the "GPL"), or
- * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-/* $Id: ssl3con.c,v 1.173 2012/03/18 00:31:19 wtc%google.com Exp $ */
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+/* $Id: ssl3con.c,v 1.192 2012/09/28 05:10:25 wtc%google.com Exp $ */
/* TODO(ekr): Implement HelloVerifyRequest on server side. OK for now. */
@@ -62,21 +27,15 @@
#include "pk11func.h"
#include "secmod.h"
+#ifndef NO_PKCS11_BYPASS
#include "blapi.h"
+#endif
#include <stdio.h>
#ifdef NSS_ENABLE_ZLIB
#include "zlib.h"
#endif
-/* DSA_SIGNATURE_LEN is deprecated and replaced by DSA1_SIGNATURE_LEN
- * in NSS 3.14. Provide a backup definition when compiling against an
- * older system NSS library.
- */
-#ifndef DSA1_SIGNATURE_LEN
-#define DSA1_SIGNATURE_LEN 40 /* Bytes */
-#endif
-
#ifndef PK11_SETATTRS
#define PK11_SETATTRS(x,id,v,l) (x)->type = (id); \
(x)->pValue=(v); (x)->ulValueLen = (l);
@@ -112,8 +71,6 @@
#define MAX_SEND_BUF_LENGTH 32000 /* watch for 16-bit integer overflow */
#define MIN_SEND_BUF_LENGTH 4000
-#define MAX_CIPHER_SUITES 20
-
/* This list of SSL3 cipher suites is sorted in descending order of
* precedence (desirability). It only includes cipher suites we implement.
* This table is modified by SSL3_SetPolicy(). The ordering of cipher suites
@@ -127,14 +84,14 @@
#endif /* NSS_ENABLE_ECC */
{ TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA, SSL_NOT_ALLOWED, PR_FALSE,PR_FALSE},
{ TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA, SSL_NOT_ALLOWED, PR_FALSE,PR_FALSE},
- { TLS_DHE_RSA_WITH_AES_256_CBC_SHA, SSL_NOT_ALLOWED, PR_FALSE,PR_FALSE},
- { TLS_DHE_DSS_WITH_AES_256_CBC_SHA, SSL_NOT_ALLOWED, PR_FALSE,PR_FALSE},
+ { TLS_DHE_RSA_WITH_AES_256_CBC_SHA, SSL_NOT_ALLOWED, PR_TRUE,PR_FALSE},
+ { TLS_DHE_DSS_WITH_AES_256_CBC_SHA, SSL_NOT_ALLOWED, PR_TRUE,PR_FALSE},
#ifdef NSS_ENABLE_ECC
{ TLS_ECDH_RSA_WITH_AES_256_CBC_SHA, SSL_NOT_ALLOWED, PR_FALSE,PR_FALSE},
{ TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA, SSL_NOT_ALLOWED, PR_FALSE,PR_FALSE},
#endif /* NSS_ENABLE_ECC */
{ TLS_RSA_WITH_CAMELLIA_256_CBC_SHA, SSL_NOT_ALLOWED, PR_FALSE,PR_FALSE},
- { TLS_RSA_WITH_AES_256_CBC_SHA, SSL_NOT_ALLOWED, PR_FALSE,PR_FALSE},
+ { TLS_RSA_WITH_AES_256_CBC_SHA, SSL_NOT_ALLOWED, PR_TRUE,PR_FALSE},
#ifdef NSS_ENABLE_ECC
{ TLS_ECDHE_ECDSA_WITH_RC4_128_SHA, SSL_NOT_ALLOWED, PR_FALSE,PR_FALSE},
@@ -145,8 +102,8 @@
{ TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA, SSL_NOT_ALLOWED, PR_FALSE,PR_FALSE},
{ TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA, SSL_NOT_ALLOWED, PR_FALSE,PR_FALSE},
{ TLS_DHE_DSS_WITH_RC4_128_SHA, SSL_NOT_ALLOWED, PR_FALSE,PR_FALSE},
- { TLS_DHE_RSA_WITH_AES_128_CBC_SHA, SSL_NOT_ALLOWED, PR_FALSE,PR_FALSE},
- { TLS_DHE_DSS_WITH_AES_128_CBC_SHA, SSL_NOT_ALLOWED, PR_FALSE,PR_FALSE},
+ { TLS_DHE_RSA_WITH_AES_128_CBC_SHA, SSL_NOT_ALLOWED, PR_TRUE,PR_FALSE},
+ { TLS_DHE_DSS_WITH_AES_128_CBC_SHA, SSL_NOT_ALLOWED, PR_TRUE,PR_FALSE},
#ifdef NSS_ENABLE_ECC
{ TLS_ECDH_RSA_WITH_RC4_128_SHA, SSL_NOT_ALLOWED, PR_FALSE,PR_FALSE},
{ TLS_ECDH_RSA_WITH_AES_128_CBC_SHA, SSL_NOT_ALLOWED, PR_FALSE,PR_FALSE},
@@ -155,33 +112,33 @@
#endif /* NSS_ENABLE_ECC */
{ TLS_RSA_WITH_SEED_CBC_SHA, SSL_NOT_ALLOWED, PR_FALSE,PR_FALSE},
{ TLS_RSA_WITH_CAMELLIA_128_CBC_SHA, SSL_NOT_ALLOWED, PR_FALSE,PR_FALSE},
- { SSL_RSA_WITH_RC4_128_SHA, SSL_NOT_ALLOWED, PR_FALSE,PR_FALSE},
+ { SSL_RSA_WITH_RC4_128_SHA, SSL_NOT_ALLOWED, PR_TRUE,PR_FALSE},
{ SSL_RSA_WITH_RC4_128_MD5, SSL_NOT_ALLOWED, PR_TRUE, PR_FALSE},
- { TLS_RSA_WITH_AES_128_CBC_SHA, SSL_NOT_ALLOWED, PR_FALSE,PR_FALSE},
+ { TLS_RSA_WITH_AES_128_CBC_SHA, SSL_NOT_ALLOWED, PR_TRUE,PR_FALSE},
#ifdef NSS_ENABLE_ECC
{ TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA, SSL_NOT_ALLOWED, PR_FALSE,PR_FALSE},
{ TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, SSL_NOT_ALLOWED, PR_FALSE,PR_FALSE},
#endif /* NSS_ENABLE_ECC */
- { SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA, SSL_NOT_ALLOWED, PR_FALSE,PR_FALSE},
- { SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA, SSL_NOT_ALLOWED, PR_FALSE,PR_FALSE},
+ { SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA, SSL_NOT_ALLOWED, PR_TRUE,PR_FALSE},
+ { SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA, SSL_NOT_ALLOWED, PR_TRUE,PR_FALSE},
#ifdef NSS_ENABLE_ECC
{ TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA, SSL_NOT_ALLOWED, PR_FALSE,PR_FALSE},
{ TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA, SSL_NOT_ALLOWED, PR_FALSE,PR_FALSE},
#endif /* NSS_ENABLE_ECC */
- { SSL_RSA_FIPS_WITH_3DES_EDE_CBC_SHA, SSL_NOT_ALLOWED, PR_TRUE, PR_FALSE},
+ { SSL_RSA_FIPS_WITH_3DES_EDE_CBC_SHA, SSL_NOT_ALLOWED, PR_FALSE, PR_FALSE},
{ SSL_RSA_WITH_3DES_EDE_CBC_SHA, SSL_NOT_ALLOWED, PR_TRUE, PR_FALSE},
{ SSL_DHE_RSA_WITH_DES_CBC_SHA, SSL_NOT_ALLOWED, PR_FALSE,PR_FALSE},
{ SSL_DHE_DSS_WITH_DES_CBC_SHA, SSL_NOT_ALLOWED, PR_FALSE,PR_FALSE},
- { SSL_RSA_FIPS_WITH_DES_CBC_SHA, SSL_NOT_ALLOWED, PR_TRUE, PR_FALSE},
- { SSL_RSA_WITH_DES_CBC_SHA, SSL_NOT_ALLOWED, PR_TRUE, PR_FALSE},
- { TLS_RSA_EXPORT1024_WITH_RC4_56_SHA, SSL_NOT_ALLOWED, PR_TRUE, PR_FALSE},
- { TLS_RSA_EXPORT1024_WITH_DES_CBC_SHA, SSL_NOT_ALLOWED, PR_TRUE, PR_FALSE},
+ { SSL_RSA_FIPS_WITH_DES_CBC_SHA, SSL_NOT_ALLOWED, PR_FALSE, PR_FALSE},
+ { SSL_RSA_WITH_DES_CBC_SHA, SSL_NOT_ALLOWED, PR_FALSE, PR_FALSE},
+ { TLS_RSA_EXPORT1024_WITH_RC4_56_SHA, SSL_NOT_ALLOWED, PR_FALSE, PR_FALSE},
+ { TLS_RSA_EXPORT1024_WITH_DES_CBC_SHA, SSL_NOT_ALLOWED, PR_FALSE, PR_FALSE},
- { SSL_RSA_EXPORT_WITH_RC4_40_MD5, SSL_NOT_ALLOWED, PR_TRUE, PR_FALSE},
- { SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD5, SSL_NOT_ALLOWED, PR_TRUE, PR_FALSE},
+ { SSL_RSA_EXPORT_WITH_RC4_40_MD5, SSL_NOT_ALLOWED, PR_FALSE, PR_FALSE},
+ { SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD5, SSL_NOT_ALLOWED, PR_FALSE, PR_FALSE},
#ifdef NSS_ENABLE_ECC
{ TLS_ECDHE_ECDSA_WITH_NULL_SHA, SSL_NOT_ALLOWED, PR_FALSE, PR_FALSE},
@@ -333,7 +290,6 @@
cipher_3des, mac_sha, kea_dhe_rsa},
#if 0
{SSL_DH_ANON_EXPORT_RC4_40_MD5, cipher_rc4_40, mac_md5, kea_dh_anon_export},
- {SSL_DH_ANON_EXPORT_RC4_40_MD5, cipher_rc4, mac_md5, kea_dh_anon_export},
{SSL_DH_ANON_EXPORT_WITH_DES40_CBC_SHA,
cipher_des40, mac_sha, kea_dh_anon_export},
{SSL_DH_ANON_DES_CBC_SHA, cipher_des, mac_sha, kea_dh_anon},
@@ -577,6 +533,31 @@
}
}
+static PRBool
+ssl3_CipherSuiteAllowedForVersion(ssl3CipherSuite cipherSuite,
+ SSL3ProtocolVersion version)
+{
+ switch (cipherSuite) {
+ /* See RFC 4346 A.5. Export cipher suites must not be used in TLS 1.1 or
+ * later. This set of cipher suites is similar to, but different from, the
+ * set of cipher suites considered exportable by SSL_IsExportCipherSuite.
+ */
+ case SSL_RSA_EXPORT_WITH_RC4_40_MD5:
+ case SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD5:
+ /* SSL_RSA_EXPORT_WITH_DES40_CBC_SHA: never implemented
+ * SSL_DH_DSS_EXPORT_WITH_DES40_CBC_SHA: never implemented
+ * SSL_DH_RSA_EXPORT_WITH_DES40_CBC_SHA: never implemented
+ * SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA: never implemented
+ * SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA: never implemented
+ * SSL_DH_ANON_EXPORT_WITH_RC4_40_MD5: never implemented
+ * SSL_DH_ANON_EXPORT_WITH_DES40_CBC_SHA: never implemented
+ */
+ return version <= SSL_LIBRARY_VERSION_TLS_1_0;
+ default:
+ return PR_TRUE;
+ }
+}
+
/* return pointer to ssl3CipherSuiteDef for suite, or NULL */
/* XXX This does a linear search. A binary search would be better. */
static const ssl3CipherSuiteDef *
@@ -920,7 +901,7 @@
hashItem.data = hash->sha;
hashItem.len = sizeof(hash->sha);
/* Allow DER encoded DSA signatures in SSL 3.0 */
- if (isTLS || buf->len != DSA1_SIGNATURE_LEN) {
+ if (isTLS || buf->len != SECKEY_SignatureLen(key)) {
signature = DSAU_DecodeDerSig(buf);
if (!signature) {
PORT_SetError(SSL_ERROR_BAD_HANDSHAKE_HASH_VALUE);
@@ -986,10 +967,13 @@
{
SECStatus rv = SECSuccess;
+#ifndef NO_PKCS11_BYPASS
if (bypassPKCS11) {
MD5_HashBuf (hashes->md5, hashBuf, bufLen);
SHA1_HashBuf(hashes->sha, hashBuf, bufLen);
- } else {
+ } else
+#endif
+ {
rv = PK11_HashBuf(SEC_OID_MD5, hashes->md5, hashBuf, bufLen);
if (rv != SECSuccess) {
ssl_MapLowLevelError(SSL_ERROR_MD5_DIGEST_FAILURE);
@@ -1410,6 +1394,7 @@
return SECSuccess;
}
+#ifndef NO_PKCS11_BYPASS
/* Initialize encryption and MAC contexts for pending spec.
* Master Secret already is derived in spec->msItem
* Caller holds Spec write lock.
@@ -1576,6 +1561,7 @@
bail_out:
return SECFailure;
}
+#endif
/* This function should probably be moved to pk11wrap and be named
* PK11_ParamFromIVAndEffectiveKeyBits
@@ -1775,6 +1761,7 @@
goto done; /* err code set by ssl3_DeriveMasterSecret */
}
}
+#ifndef NO_PKCS11_BYPASS
if (ss->opt.bypassPKCS11 && pwSpec->msItem.len && pwSpec->msItem.data) {
/* Double Bypass succeeded in extracting the master_secret */
const ssl3KEADef * kea_def = ss->ssl3.hs.kea_def;
@@ -1789,7 +1776,9 @@
if (rv == SECSuccess) {
rv = ssl3_InitPendingContextsBypass(ss);
}
- } else if (pwSpec->master_secret) {
+ } else
+#endif
+ if (pwSpec->master_secret) {
rv = ssl3_DeriveConnectionKeysPKCS11(ss);
if (rv == SECSuccess) {
rv = ssl3_InitPendingContextsPKCS11(ss);
@@ -1875,7 +1864,9 @@
{
const ssl3MACDef * mac_def;
SECStatus rv;
+#ifndef NO_PKCS11_BYPASS
PRBool isTLS;
+#endif
unsigned int tempLen;
unsigned char temp[MAX_MAC_LENGTH];
@@ -1899,7 +1890,9 @@
temp[9] = MSB(inputLength);
temp[10] = LSB(inputLength);
tempLen = 11;
+#ifndef NO_PKCS11_BYPASS
isTLS = PR_FALSE;
+#endif
} else {
/* New TLS hash includes version. */
if (isDTLS) {
@@ -1915,7 +1908,9 @@
temp[11] = MSB(inputLength);
temp[12] = LSB(inputLength);
tempLen = 13;
+#ifndef NO_PKCS11_BYPASS
isTLS = PR_TRUE;
+#endif
}
PRINT_BUF(95, (NULL, "frag hash1: temp", temp, tempLen));
@@ -1926,15 +1921,8 @@
*outLength = 0;
return SECSuccess;
}
- if (! spec->bypassCiphers) {
- PK11Context *mac_context =
- (useServerMacKey ? spec->server.write_mac_context
- : spec->client.write_mac_context);
- rv = PK11_DigestBegin(mac_context);
- rv |= PK11_DigestOp(mac_context, temp, tempLen);
- rv |= PK11_DigestOp(mac_context, input, inputLength);
- rv |= PK11_DigestFinal(mac_context, outbuf, outLength, spec->mac_size);
- } else {
+#ifndef NO_PKCS11_BYPASS
+ if (spec->bypassCiphers) {
/* bypass version */
const SECHashObject *hashObj = NULL;
unsigned int pad_bytes = 0;
@@ -2017,6 +2005,16 @@
}
#undef cx
}
+ } else
+#endif
+ {
+ PK11Context *mac_context =
+ (useServerMacKey ? spec->server.write_mac_context
+ : spec->client.write_mac_context);
+ rv = PK11_DigestBegin(mac_context);
+ rv |= PK11_DigestOp(mac_context, temp, tempLen);
+ rv |= PK11_DigestOp(mac_context, input, inputLength);
+ rv |= PK11_DigestFinal(mac_context, outbuf, outLength, spec->mac_size);
}
PORT_Assert(rv != SECSuccess || *outLength == (unsigned)spec->mac_size);
@@ -2802,7 +2800,7 @@
/*
- * Send handshake_Failure alert. Set generic error number.
+ * Send decode_error alert. Set generic error number.
*/
SECStatus
ssl3_DecodeError(sslSocket *ss)
@@ -3173,6 +3171,7 @@
ssl_MapLowLevelError(SSL_ERROR_SESSION_KEY_GEN_FAILURE);
return rv;
}
+#ifndef NO_PKCS11_BYPASS
if (ss->opt.bypassPKCS11) {
SECItem * keydata;
/* In hope of doing a "double bypass",
@@ -3208,6 +3207,7 @@
return SECFailure;
}
}
+#endif
return SECSuccess;
}
@@ -3355,11 +3355,14 @@
{
SECStatus rv = SECSuccess;
+#ifndef NO_PKCS11_BYPASS
if (ss->opt.bypassPKCS11) {
ss->ssl3.hs.messages.len = 0;
MD5_Begin((MD5Context *)ss->ssl3.hs.md5_cx);
SHA1_Begin((SHA1Context *)ss->ssl3.hs.sha_cx);
- } else {
+ } else
+#endif
+ {
rv = PK11_DigestBegin(ss->ssl3.hs.md5);
if (rv != SECSuccess) {
ssl_MapLowLevelError(SSL_ERROR_MD5_DIGEST_FAILURE);
@@ -3386,11 +3389,14 @@
* that the master secret will wind up in ...
*/
SSL_TRC(30,("%d: SSL3[%d]: start handshake hashes", SSL_GETPID(), ss->fd));
+#ifndef NO_PKCS11_BYPASS
if (ss->opt.bypassPKCS11) {
PORT_Assert(!ss->ssl3.hs.messages.buf && !ss->ssl3.hs.messages.space);
ss->ssl3.hs.messages.buf = NULL;
ss->ssl3.hs.messages.space = 0;
- } else {
+ } else
+#endif
+ {
ss->ssl3.hs.md5 = md5 = PK11_CreateDigestContext(SEC_OID_MD5);
ss->ssl3.hs.sha = sha = PK11_CreateDigestContext(SEC_OID_SHA1);
if (md5 == NULL) {
@@ -3438,6 +3444,7 @@
PRINT_BUF(90, (NULL, "MD5 & SHA handshake hash input:", b, l));
+#ifndef NO_PKCS11_BYPASS
if (ss->opt.bypassPKCS11) {
MD5_Update((MD5Context *)ss->ssl3.hs.md5_cx, b, l);
SHA1_Update((SHA1Context *)ss->ssl3.hs.sha_cx, b, l);
@@ -3446,6 +3453,7 @@
#endif
return rv;
}
+#endif
rv = PK11_DigestOp(ss->ssl3.hs.md5, b, l);
if (rv != SECSuccess) {
ssl_MapLowLevelError(SSL_ERROR_MD5_DIGEST_FAILURE);
@@ -3739,6 +3747,7 @@
PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss) );
+#ifndef NO_PKCS11_BYPASS
if (ss->opt.bypassPKCS11) {
/* compute them without PKCS11 */
PRUint64 md5_cx[MAX_MAC_CONTEXT_LLONGS];
@@ -3821,7 +3830,9 @@
rv = SECSuccess;
#undef md5cx
#undef shacx
- } else {
+ } else
+#endif
+ {
/* compute hases with PKCS11 */
PK11Context * md5;
PK11Context * sha = NULL;
@@ -4294,7 +4305,8 @@
}
if (ss->firstHsDone) {
- /* Work around the Windows SChannel bug described above. */
+ /* The client hello version must stay unchanged to work around
+ * the Windows SChannel bug described above. */
PORT_Assert(ss->version == ss->clientHelloVersion);
}
ss->clientHelloVersion = ss->version;
@@ -4910,9 +4922,11 @@
/* hexEncode hex encodes |length| bytes from |in| and writes it as |length*2|
* bytes to |out|. */
-static void hexEncode(char *out, const unsigned char *in, size_t length) {
+static void
+hexEncode(char *out, const unsigned char *in, unsigned int length)
+{
static const char hextable[] = "0123456789abcdef";
- size_t i;
+ unsigned int i;
for (i = 0; i < length; i++) {
*(out++) = hextable[in[i] >> 4];
@@ -5382,8 +5396,17 @@
ssl3_config_match_init(ss);
for (i = 0; i < ssl_V3_SUITES_IMPLEMENTED; i++) {
ssl3CipherSuiteCfg *suite = &ss->cipherSuites[i];
- if ((temp == suite->cipher_suite) &&
- (config_match(suite, ss->ssl3.policy, PR_TRUE))) {
+ if (temp == suite->cipher_suite) {
+ if (!config_match(suite, ss->ssl3.policy, PR_TRUE)) {
+ break; /* failure */
+ }
+ if (!ssl3_CipherSuiteAllowedForVersion(suite->cipher_suite,
+ ss->version)) {
+ desc = handshake_failure;
+ errCode = SSL_ERROR_CIPHER_DISALLOWED_FOR_VERSION;
+ goto alert_loser;
+ }
+
suite_found = PR_TRUE;
break; /* success */
}
@@ -5408,8 +5431,10 @@
}
suite_found = PR_FALSE;
for (i = 0; i < compressionMethodsCount; i++) {
- if (temp == compressions[i] &&
- compressionEnabled(ss, compressions[i])) {
+ if (temp == compressions[i]) {
+ if (!compressionEnabled(ss, compressions[i])) {
+ break; /* failure */
+ }
suite_found = PR_TRUE;
break; /* success */
}
@@ -5494,12 +5519,14 @@
PK11SymKey * wrapKey; /* wrapping key */
CK_FLAGS keyFlags = 0;
+#ifndef NO_PKCS11_BYPASS
if (ss->opt.bypassPKCS11) {
/* we cannot restart a non-bypass session in a
** bypass socket.
*/
break;
}
+#endif
/* unwrap master secret with PKCS11 */
slot = SECMOD_LookupSlot(sid->u.ssl3.masterModuleID,
sid->u.ssl3.masterSlotID);
@@ -5534,6 +5561,7 @@
if (pwSpec->master_secret == NULL) {
break; /* errorCode set just after call to UnwrapSymKey. */
}
+#ifndef NO_PKCS11_BYPASS
} else if (ss->opt.bypassPKCS11) {
/* MS is not wrapped */
wrappedMS.data = sid->u.ssl3.keys.wrapped_master_secret;
@@ -5541,6 +5569,7 @@
memcpy(pwSpec->raw_master_secret, wrappedMS.data, wrappedMS.len);
pwSpec->msItem.data = pwSpec->raw_master_secret;
pwSpec->msItem.len = wrappedMS.len;
+#endif
} else {
/* We CAN restart a bypass session in a non-bypass socket. */
/* need to import the raw master secret to session object */
@@ -5578,6 +5607,7 @@
ssl3_CopyPeerCertsFromSID(ss, sid);
}
+
/* NULL value for PMS signifies re-use of the old MS */
rv = ssl3_InitPendingCipherSpec(ss, NULL);
if (rv != SECSuccess) {
@@ -5640,10 +5670,10 @@
return SECFailure;
}
-/* ssl3_BigIntGreaterThan1 returns true iff |mpint|, taken as an unsigned,
+/* ssl3_BigIntGreaterThanOne returns true iff |mpint|, taken as an unsigned,
* big-endian integer is > 1 */
static PRBool
-ssl3_BigIntGreaterThan1(const SECItem* mpint) {
+ssl3_BigIntGreaterThanOne(const SECItem* mpint) {
unsigned char firstNonZeroByte = 0;
unsigned int i;
@@ -5659,8 +5689,8 @@
if (firstNonZeroByte > 1)
return PR_TRUE;
- // firstNonZeroByte == 1, therefore mpint > 1 iff the first non-zero byte
- // is followed by another byte.
+ /* firstNonZeroByte == 1, therefore mpint > 1 iff the first non-zero byte
+ * is followed by another byte. */
return (i < mpint->len - 1);
}
@@ -5795,13 +5825,13 @@
if (rv != SECSuccess) {
goto loser; /* malformed. */
}
- if (dh_g.len > dh_p.len || !ssl3_BigIntGreaterThan1(&dh_g))
+ if (dh_g.len > dh_p.len || !ssl3_BigIntGreaterThanOne(&dh_g))
goto alert_loser;
rv = ssl3_ConsumeHandshakeVariable(ss, &dh_Ys, 2, &b, &length);
if (rv != SECSuccess) {
goto loser; /* malformed. */
}
- if (dh_Ys.len > dh_p.len || !ssl3_BigIntGreaterThan1(&dh_Ys))
+ if (dh_Ys.len > dh_p.len || !ssl3_BigIntGreaterThanOne(&dh_Ys))
goto alert_loser;
rv = ssl3_ConsumeHandshakeVariable(ss, &signature, 2, &b, &length);
if (rv != SECSuccess) {
@@ -6949,13 +6979,26 @@
#endif
/* Select a cipher suite.
+ **
** NOTE: This suite selection algorithm should be the same as the one in
- ** ssl3_HandleV2ClientHello().
+ ** ssl3_HandleV2ClientHello().
+ **
+ ** If TLS 1.0 is enabled, we could handle the case where the client
+ ** offered TLS 1.1 but offered only export cipher suites by choosing TLS
+ ** 1.0 and selecting one of those export cipher suites. However, a secure
+ ** TLS 1.1 client should not have export cipher suites enabled at all,
+ ** and a TLS 1.1 client should definitely not be offering *only* export
+ ** cipher suites. Therefore, we refuse to negotiate export cipher suites
+ ** with any client that indicates support for TLS 1.1 or higher when we
+ ** (the server) have TLS 1.1 support enabled.
*/
for (j = 0; j < ssl_V3_SUITES_IMPLEMENTED; j++) {
ssl3CipherSuiteCfg *suite = &ss->cipherSuites[j];
- if (!config_match(suite, ss->ssl3.policy, PR_TRUE))
+ if (!config_match(suite, ss->ssl3.policy, PR_TRUE) ||
+ !ssl3_CipherSuiteAllowedForVersion(suite->cipher_suite,
+ ss->version)) {
continue;
+ }
for (i = 0; i + 1 < suites.len; i += 2) {
PRUint16 suite_i = (suites.data[i] << 8) | suites.data[i + 1];
if (suite_i == suite->cipher_suite) {
@@ -6972,9 +7015,10 @@
suite_found:
/* Look for a matching compression algorithm. */
for (i = 0; i < comps.len; i++) {
+ if (!compressionEnabled(ss, comps.data[i]))
+ continue;
for (j = 0; j < compressionMethodsCount; j++) {
- if (comps.data[i] == compressions[j] &&
- compressionEnabled(ss, compressions[j])) {
+ if (comps.data[i] == compressions[j]) {
ss->ssl3.hs.compression =
(SSLCompressionMethod)compressions[j];
goto compression_found;
@@ -7000,7 +7044,8 @@
SECItem wrappedMS; /* wrapped key */
if (sid->version != ss->version ||
- sid->u.ssl3.cipherSuite != ss->ssl3.hs.cipher_suite) {
+ sid->u.ssl3.cipherSuite != ss->ssl3.hs.cipher_suite ||
+ sid->u.ssl3.compression != ss->ssl3.hs.compression) {
break; /* not an error */
}
@@ -7020,12 +7065,14 @@
if (sid->u.ssl3.keys.msIsWrapped) {
PK11SymKey * wrapKey; /* wrapping key */
CK_FLAGS keyFlags = 0;
+#ifndef NO_PKCS11_BYPASS
if (ss->opt.bypassPKCS11) {
/* we cannot restart a non-bypass session in a
** bypass socket.
*/
break;
}
+#endif
wrapKey = getWrappingKey(ss, NULL, sid->u.ssl3.exchKeyType,
sid->u.ssl3.masterWrapMech,
@@ -7051,12 +7098,14 @@
if (pwSpec->master_secret == NULL) {
break; /* not an error */
}
+#ifndef NO_PKCS11_BYPASS
} else if (ss->opt.bypassPKCS11) {
wrappedMS.data = sid->u.ssl3.keys.wrapped_master_secret;
wrappedMS.len = sid->u.ssl3.keys.wrapped_master_secret_len;
memcpy(pwSpec->raw_master_secret, wrappedMS.data, wrappedMS.len);
pwSpec->msItem.data = pwSpec->raw_master_secret;
pwSpec->msItem.len = wrappedMS.len;
+#endif
} else {
/* We CAN restart a bypass session in a non-bypass socket. */
/* need to import the raw master secret to session object */
@@ -7460,13 +7509,19 @@
}
/* Select a cipher suite.
+ **
** NOTE: This suite selection algorithm should be the same as the one in
- ** ssl3_HandleClientHello().
+ ** ssl3_HandleClientHello().
+ **
+ ** See the comments about export cipher suites in ssl3_HandleClientHello().
*/
for (j = 0; j < ssl_V3_SUITES_IMPLEMENTED; j++) {
ssl3CipherSuiteCfg *suite = &ss->cipherSuites[j];
- if (!config_match(suite, ss->ssl3.policy, PR_TRUE))
+ if (!config_match(suite, ss->ssl3.policy, PR_TRUE) ||
+ !ssl3_CipherSuiteAllowedForVersion(suite->cipher_suite,
+ ss->version)) {
continue;
+ }
for (i = 0; i+2 < suite_length; i += 3) {
PRUint32 suite_i = (suites[i] << 16)|(suites[i+1] << 8)|suites[i+2];
if (suite_i == suite->cipher_suite) {
@@ -7792,8 +7847,6 @@
nnames = ca_list->nnames;
}
- /* There used to be a test here to require a CA, but there
- * are cases where you want to have no CAs offered. */
for (i = 0, name = names; i < nnames; i++, name++) {
calen += 2 + name->len;
}
@@ -7999,10 +8052,12 @@
SECKEYPrivateKey *serverKey)
{
PK11SymKey * pms;
+#ifndef NO_PKCS11_BYPASS
unsigned char * cr = (unsigned char *)&ss->ssl3.hs.client_random;
unsigned char * sr = (unsigned char *)&ss->ssl3.hs.server_random;
ssl3CipherSpec * pwSpec = ss->ssl3.pwSpec;
unsigned int outLen = 0;
+#endif
PRBool isTLS = PR_FALSE;
SECStatus rv;
SECItem enc_pms;
@@ -8032,6 +8087,7 @@
isTLS = (PRBool)(ss->ssl3.hs.kea_def->tls_keygen != 0);
}
+#ifndef NO_PKCS11_BYPASS
if (ss->opt.bypassPKCS11) {
/* TRIPLE BYPASS, get PMS directly from RSA decryption.
* Use PK11_PrivDecryptPKCS1 to decrypt the PMS to a buffer,
@@ -8068,8 +8124,12 @@
PK11_GenerateRandom(pwSpec->msItem.data, pwSpec->msItem.len);
}
rv = ssl3_InitPendingCipherSpec(ss, NULL);
- } else {
+ } else
+#endif
+ {
+#ifndef NO_PKCS11_BYPASS
double_bypass:
+#endif
/*
* unwrap pms out of the incoming buffer
* Note: CKM_SSL3_MASTER_KEY_DERIVE is NOT the mechanism used to do
@@ -8961,6 +9021,11 @@
PK11_DestroyContext(prf_context, PR_TRUE);
} else {
/* bypass PKCS11 */
+#ifdef NO_PKCS11_BYPASS
+ PORT_Assert(spec->master_secret);
+ PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
+ rv = SECFailure;
+#else
SECItem inData = { siBuffer, };
SECItem outData = { siBuffer, };
PRBool isFIPS = PR_FALSE;
@@ -8971,6 +9036,7 @@
outData.len = outLen;
rv = TLS_PRF(&spec->msItem, label, &inData, &outData, isFIPS);
PORT_Assert(rv != SECSuccess || outData.len == outLen);
+#endif
}
return rv;
}
@@ -9009,6 +9075,68 @@
return rv;
}
+/* called from ssl3_SendFinished
+ *
+ * This function is simply a debugging aid and therefore does not return a
+ * SECStatus. */
+static void
+ssl3_RecordKeyLog(sslSocket *ss)
+{
+ sslSessionID *sid;
+ SECStatus rv;
+ SECItem *keyData;
+ char buf[14 /* "CLIENT_RANDOM " */ +
+ SSL3_RANDOM_LENGTH*2 /* client_random */ +
+ 1 /* " " */ +
+ 48*2 /* master secret */ +
+ 1 /* new line */];
+ unsigned int j;
+
+ PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss));
+
+ sid = ss->sec.ci.sid;
+
+ if (!ssl_keylog_iob)
+ return;
+
+ rv = PK11_ExtractKeyValue(ss->ssl3.cwSpec->master_secret);
+ if (rv != SECSuccess)
+ return;
+
+ ssl_GetSpecReadLock(ss);
+
+ /* keyData does not need to be freed. */
+ keyData = PK11_GetKeyData(ss->ssl3.cwSpec->master_secret);
+ if (!keyData || !keyData->data || keyData->len != 48) {
+ ssl_ReleaseSpecReadLock(ss);
+ return;
+ }
+
+ /* https://developer.mozilla.org/en/NSS_Key_Log_Format */
+
+ /* There could be multiple, concurrent writers to the
+ * keylog, so we have to do everything in a single call to
+ * fwrite. */
+
+ memcpy(buf, "CLIENT_RANDOM ", 14);
+ j = 14;
+ hexEncode(buf + j, ss->ssl3.hs.client_random.rand, SSL3_RANDOM_LENGTH);
+ j += SSL3_RANDOM_LENGTH*2;
+ buf[j++] = ' ';
+ hexEncode(buf + j, keyData->data, 48);
+ j += 48*2;
+ buf[j++] = '\n';
+
+ PORT_Assert(j == sizeof(buf));
+
+ ssl_ReleaseSpecReadLock(ss);
+
+ if (fwrite(buf, sizeof(buf), 1, ssl_keylog_iob) != 1)
+ return;
+ fflush(ssl_keylog_iob);
+ return;
+}
+
/* called from ssl3_SendClientSecondRound
* ssl3_HandleFinished
*/
@@ -9167,69 +9295,6 @@
return SECSuccess;
}
-/* called from ssl3_SendFinished
- *
- * Caller must already hold the SpecReadLock. (wish we could assert that!).
- * This function is simply a debugging aid and therefore does not return a
- * SECStatus. */
-static void
-ssl3_RecordKeyLog(sslSocket *ss)
-{
- sslSessionID *sid;
- SECStatus rv;
- SECItem *keyData;
- char buf[14 /* "CLIENT_RANDOM " */ +
- SSL3_RANDOM_LENGTH*2 /* client_random */ +
- 1 /* " " */ +
- 48*2 /* master secret */ +
- 1 /* new line */];
- unsigned int j;
-
- PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss));
-
- sid = ss->sec.ci.sid;
-
- if (!ssl_keylog_iob)
- return;
-
- rv = PK11_ExtractKeyValue(ss->ssl3.cwSpec->master_secret);
- if (rv != SECSuccess)
- return;
-
- ssl_GetSpecReadLock(ss);
-
- /* keyData does not need to be freed. */
- keyData = PK11_GetKeyData(ss->ssl3.cwSpec->master_secret);
- if (!keyData || !keyData->data || keyData->len != 48) {
- ssl_ReleaseSpecReadLock(ss);
- return;
- }
-
- /* https://developer.mozilla.org/en/NSS_Key_Log_Format */
-
- /* There could be multiple, concurrent writers to the
- * keylog, so we have to do everything in a single call to
- * fwrite. */
-
- memcpy(buf, "CLIENT_RANDOM ", 14);
- j = 14;
- hexEncode(buf + j, ss->ssl3.hs.client_random.rand, SSL3_RANDOM_LENGTH);
- j += SSL3_RANDOM_LENGTH*2;
- buf[j++] = ' ';
- hexEncode(buf + j, keyData->data, 48);
- j += 48*2;
- buf[j++] = '\n';
-
- PORT_Assert(j == sizeof(buf));
-
- ssl_ReleaseSpecReadLock(ss);
-
- if (fwrite(buf, sizeof(buf), 1, ssl_keylog_iob) != 1)
- return;
- fflush(ssl_keylog_iob);
- return;
-}
-
/* called from ssl3_HandleServerHelloDone
* ssl3_HandleClientHello
* ssl3_HandleFinished
@@ -9935,7 +10000,7 @@
/* must be copied to msg_body and dealt with from there */
unsigned int bytes;
- PORT_Assert(ss->ssl3.hs.msg_body.len <= ss->ssl3.hs.msg_len);
+ PORT_Assert(ss->ssl3.hs.msg_body.len < ss->ssl3.hs.msg_len);
bytes = PR_MIN(buf->len, ss->ssl3.hs.msg_len - ss->ssl3.hs.msg_body.len);
/* Grow the buffer if needed */
@@ -9957,18 +10022,19 @@
if (ss->ssl3.hs.msg_body.len == ss->ssl3.hs.msg_len) {
rv = ssl3_HandleHandshakeMessage(
ss, ss->ssl3.hs.msg_body.buf, ss->ssl3.hs.msg_len);
- /*
- * XXX This appears to be wrong. This error handling
- * should clean up after a SECWouldBlock return, like the
- * error handling used 40 lines before/above this one,
- */
- if (rv != SECSuccess) {
- /* ssl3_HandleHandshakeMessage MUST set error code. */
+ if (rv == SECFailure) {
+ /* This test wants to fall through on either
+ * SECSuccess or SECWouldBlock.
+ * ssl3_HandleHandshakeMessage MUST set error code.
+ */
return rv;
}
ss->ssl3.hs.msg_body.len = 0;
- ss->ssl3.hs.msg_len = 0;
+ ss->ssl3.hs.msg_len = 0;
ss->ssl3.hs.header_bytes = 0;
+ if (rv != SECSuccess) { /* return if SECWouldBlock. */
+ return rv;
+ }
} else {
PORT_Assert(buf->len == 0);
break;
@@ -10457,13 +10523,8 @@
ss->ssl3.hs.recvMessageSeq = 0;
ss->ssl3.hs.rtTimeoutMs = INITIAL_DTLS_TIMEOUT_MS;
ss->ssl3.hs.rtRetries = 0;
-
- /* Have to allocate this because ssl_FreeSocket relocates
- * this structure in DEBUG mode */
- if (!(ss->ssl3.hs.lastMessageFlight = PORT_New(PRCList)))
- return SECFailure;
ss->ssl3.hs.recvdHighWater = -1;
- PR_INIT_CLIST(ss->ssl3.hs.lastMessageFlight);
+ PR_INIT_CLIST(&ss->ssl3.hs.lastMessageFlight);
dtls_SetMTU(ss, 0); /* Set the MTU to the highest plateau */
}
@@ -10836,10 +10897,12 @@
}
/* clean up handshake */
+#ifndef NO_PKCS11_BYPASS
if (ss->opt.bypassPKCS11) {
SHA1_DestroyContext((SHA1Context *)ss->ssl3.hs.sha_cx, PR_FALSE);
MD5_DestroyContext((MD5Context *)ss->ssl3.hs.md5_cx, PR_FALSE);
}
+#endif
if (ss->ssl3.hs.md5) {
PK11_DestroyContext(ss->ssl3.hs.md5,PR_TRUE);
}
@@ -10868,10 +10931,7 @@
/* Destroy the DTLS data */
if (IS_DTLS(ss)) {
- if (ss->ssl3.hs.lastMessageFlight) {
- dtls_FreeHandshakeMessages(ss->ssl3.hs.lastMessageFlight);
- PORT_Free(ss->ssl3.hs.lastMessageFlight);
- }
+ dtls_FreeHandshakeMessages(&ss->ssl3.hs.lastMessageFlight);
if (ss->ssl3.hs.recvdFragments.buf) {
PORT_Free(ss->ssl3.hs.recvdFragments.buf);
}
« no previous file with comments | « net/third_party/nss/ssl/ssl.rc ('k') | net/third_party/nss/ssl/ssl3ecc.c » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698