| 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);
|
| }
|
|
|