summaryrefslogtreecommitdiff
path: root/security/nss/lib/ssl/ssl3con.c
diff options
context:
space:
mode:
Diffstat (limited to 'security/nss/lib/ssl/ssl3con.c')
-rw-r--r--security/nss/lib/ssl/ssl3con.c794
1 files changed, 382 insertions, 412 deletions
diff --git a/security/nss/lib/ssl/ssl3con.c b/security/nss/lib/ssl/ssl3con.c
index 186ce23f3d..5cbe2bd094 100644
--- a/security/nss/lib/ssl/ssl3con.c
+++ b/security/nss/lib/ssl/ssl3con.c
@@ -38,13 +38,6 @@
#include "zlib.h"
#endif
-#ifndef PK11_SETATTRS
-#define PK11_SETATTRS(x, id, v, l) \
- (x)->type = (id); \
- (x)->pValue = (v); \
- (x)->ulValueLen = (l);
-#endif
-
static PK11SymKey *ssl3_GenerateRSAPMS(sslSocket *ss, ssl3CipherSpec *spec,
PK11SlotInfo *serverKeySlot);
static SECStatus ssl3_DeriveMasterSecret(sslSocket *ss, PK11SymKey *pms);
@@ -64,7 +57,7 @@ static SECStatus ssl3_HandleServerHelloPart2(sslSocket *ss,
const SECItem *sidBytes,
int *retErrCode);
static SECStatus ssl3_HandlePostHelloHandshakeMessage(sslSocket *ss,
- SSL3Opaque *b,
+ PRUint8 *b,
PRUint32 length,
SSL3Hashes *hashesPtr);
static SECStatus ssl3_FlushHandshakeMessages(sslSocket *ss, PRInt32 flags);
@@ -273,10 +266,6 @@ static const /*SSL3ClientCertificateType */ PRUint8 certificate_types[] = {
ct_DSS_sign,
};
-/* This global item is used only in servers. It is is initialized by
-** SSL_ConfigSecureServer(), and is used in ssl3_SendCertificateRequest().
-*/
-CERTDistNames *ssl3_server_ca_list = NULL;
static SSL3Statistics ssl3stats;
/* Record protection algorithms, indexed by SSL3BulkCipher.
@@ -863,12 +852,10 @@ ssl_HasCert(const sslSocket *ss, SSLAuthType authType)
cursor != &ss->serverCerts;
cursor = PR_NEXT_LINK(cursor)) {
sslServerCert *cert = (sslServerCert *)cursor;
- if (cert->certType.authType != authType) {
- continue;
- }
if (!cert->serverKeyPair ||
!cert->serverKeyPair->privKey ||
- !cert->serverCertChain) {
+ !cert->serverCertChain ||
+ !SSL_CERT_IS(cert, authType)) {
continue;
}
/* When called from ssl3_config_match_init(), all the EC curves will be
@@ -879,7 +866,7 @@ ssl_HasCert(const sslSocket *ss, SSLAuthType authType)
if ((authType == ssl_auth_ecdsa ||
authType == ssl_auth_ecdh_ecdsa ||
authType == ssl_auth_ecdh_rsa) &&
- !ssl_NamedGroupEnabled(ss, cert->certType.namedCurve)) {
+ !ssl_NamedGroupEnabled(ss, cert->namedCurve)) {
continue;
}
return PR_TRUE;
@@ -1044,8 +1031,9 @@ Null_Cipher(void *ctx, unsigned char *output, int *outputLen, int maxOutputLen,
return SECFailure;
}
*outputLen = inputLen;
- if (input != output)
+ if (inputLen > 0 && input != output) {
PORT_Memcpy(output, input, inputLen);
+ }
return SECSuccess;
}
@@ -1084,14 +1072,15 @@ ssl3_NegotiateVersion(sslSocket *ss, SSL3ProtocolVersion peerVersion,
/* Used by the client when the server produces a version number.
* This reads, validates, and normalizes the value. */
SECStatus
-ssl_ClientReadVersion(sslSocket *ss, SSL3Opaque **b, unsigned int *len,
+ssl_ClientReadVersion(sslSocket *ss, PRUint8 **b, unsigned int *len,
SSL3ProtocolVersion *version)
{
SSL3ProtocolVersion v;
- PRInt32 temp;
+ PRUint32 temp;
+ SECStatus rv;
- temp = ssl3_ConsumeHandshakeNumber(ss, 2, b, len);
- if (temp < 0) {
+ rv = ssl3_ConsumeHandshakeNumber(ss, &temp, 2, b, len);
+ if (rv != SECSuccess) {
return SECFailure; /* alert has been sent */
}
@@ -1624,10 +1613,6 @@ ssl3_SetupPendingCipherSpec(sslSocket *ss)
pwSpec->compressContext = NULL;
pwSpec->decompressContext = NULL;
- if (ss->version >= SSL_LIBRARY_VERSION_TLS_1_3) {
- PORT_Assert(ss->ssl3.hs.kea_def->ephemeral);
- PORT_Assert(pwSpec->cipher_def->type == type_aead);
- }
ssl_ReleaseSpecWriteLock(ss); /*******************************/
return SECSuccess;
}
@@ -1777,29 +1762,6 @@ ssl3_InitCompressionContext(ssl3CipherSpec *pwSpec)
return SECSuccess;
}
-/* This function should probably be moved to pk11wrap and be named
- * PK11_ParamFromIVAndEffectiveKeyBits
- */
-static SECItem *
-ssl3_ParamFromIV(CK_MECHANISM_TYPE mtype, SECItem *iv, CK_ULONG ulEffectiveBits)
-{
- SECItem *param = PK11_ParamFromIV(mtype, iv);
- if (param && param->data && param->len >= sizeof(CK_RC2_PARAMS)) {
- switch (mtype) {
- case CKM_RC2_KEY_GEN:
- case CKM_RC2_ECB:
- case CKM_RC2_CBC:
- case CKM_RC2_MAC:
- case CKM_RC2_MAC_GENERAL:
- case CKM_RC2_CBC_PAD:
- *(CK_RC2_PARAMS *)param->data = ulEffectiveBits;
- default:
- break;
- }
- }
- return param;
-}
-
/* ssl3_BuildRecordPseudoHeader writes the SSL/TLS pseudo-header (the data
* which is included in the MAC or AEAD additional data) to |out| and returns
* its length. See https://tools.ietf.org/html/rfc5246#section-6.2.3.3 for the
@@ -1981,7 +1943,6 @@ ssl3_InitPendingContexts(sslSocket *ss)
CK_MECHANISM_TYPE mechanism;
CK_MECHANISM_TYPE mac_mech;
CK_ULONG macLength;
- CK_ULONG effKeyBits;
SECItem iv;
SECItem mac_param;
SSLCipherAlgorithm calg;
@@ -2051,14 +2012,13 @@ ssl3_InitPendingContexts(sslSocket *ss)
return SECSuccess;
}
mechanism = ssl3_Alg2Mech(calg);
- effKeyBits = cipher_def->key_size * BPB;
/*
* build the server context
*/
iv.data = pwSpec->server.write_iv;
iv.len = cipher_def->iv_size;
- param = ssl3_ParamFromIV(mechanism, &iv, effKeyBits);
+ param = PK11_ParamFromIV(mechanism, &iv);
if (param == NULL) {
ssl_MapLowLevelError(SSL_ERROR_IV_PARAM_FAILURE);
goto fail;
@@ -2082,7 +2042,7 @@ ssl3_InitPendingContexts(sslSocket *ss)
iv.data = pwSpec->client.write_iv;
iv.len = cipher_def->iv_size;
- param = ssl3_ParamFromIV(mechanism, &iv, effKeyBits);
+ param = PK11_ParamFromIV(mechanism, &iv);
if (param == NULL) {
ssl_MapLowLevelError(SSL_ERROR_IV_PARAM_FAILURE);
goto fail;
@@ -2256,7 +2216,7 @@ ssl3_ComputeRecordMAC(
PRBool useServerMacKey,
const unsigned char *header,
unsigned int headerLen,
- const SSL3Opaque *input,
+ const PRUint8 *input,
int inputLength,
unsigned char *outbuf,
unsigned int *outLength)
@@ -2303,7 +2263,7 @@ ssl3_ComputeRecordMACConstantTime(
PRBool useServerMacKey,
const unsigned char *header,
unsigned int headerLen,
- const SSL3Opaque *input,
+ const PRUint8 *input,
int inputLen,
int originalLen,
unsigned char *outbuf,
@@ -2408,7 +2368,7 @@ ssl3_CompressMACEncryptRecord(ssl3CipherSpec *cwSpec,
PRBool isDTLS,
PRBool capRecordVersion,
SSL3ContentType type,
- const SSL3Opaque *pIn,
+ const PRUint8 *pIn,
PRUint32 contentLen,
sslBuffer *wrBuf)
{
@@ -2577,7 +2537,7 @@ ssl3_CompressMACEncryptRecord(ssl3CipherSpec *cwSpec,
SECStatus
ssl_ProtectRecord(sslSocket *ss, ssl3CipherSpec *cwSpec,
PRBool capRecordVersion, SSL3ContentType type,
- const SSL3Opaque *pIn, PRUint32 contentLen, sslBuffer *wrBuf)
+ const PRUint8 *pIn, PRUint32 contentLen, sslBuffer *wrBuf)
{
const ssl3BulkCipherDef *cipher_def = cwSpec->cipher_def;
PRUint16 headerLen;
@@ -2694,14 +2654,15 @@ PRInt32
ssl3_SendRecord(sslSocket *ss,
ssl3CipherSpec *cwSpec, /* non-NULL for DTLS retransmits */
SSL3ContentType type,
- const SSL3Opaque *pIn, /* input buffer */
- PRInt32 nIn, /* bytes of input */
+ const PRUint8 *pIn, /* input buffer */
+ PRInt32 nIn, /* bytes of input */
PRInt32 flags)
{
sslBuffer *wrBuf = &ss->sec.writeBuf;
SECStatus rv;
PRInt32 totalSent = 0;
PRBool capRecordVersion;
+ ssl3CipherSpec *spec;
SSL_TRC(3, ("%d: SSL3[%d] SendRecord type: %s nIn=%d",
SSL_GETPID(), ss->fd, ssl3_DecodeContentType(type),
@@ -2733,10 +2694,7 @@ ssl3_SendRecord(sslSocket *ss,
** trying to send an alert.
*/
PR_ASSERT(type == content_alert);
- rv = ssl3_InitState(ss);
- if (rv != SECSuccess) {
- return SECFailure; /* ssl3_InitState has set the error code. */
- }
+ ssl3_InitState(ss);
}
/* check for Token Presence */
@@ -2806,11 +2764,12 @@ ssl3_SendRecord(sslSocket *ss,
PORT_Assert(IS_DTLS(ss) &&
(type == content_handshake ||
type == content_change_cipher_spec));
+ spec = cwSpec;
} else {
- cwSpec = ss->ssl3.cwSpec;
+ spec = ss->ssl3.cwSpec;
}
- rv = ssl_ProtectRecord(ss, cwSpec, !IS_DTLS(ss) && capRecordVersion,
+ rv = ssl_ProtectRecord(ss, spec, !IS_DTLS(ss) && capRecordVersion,
type, pIn, contentLen, wrBuf);
if (rv == SECSuccess) {
PRINT_BUF(50, (ss, "send (encrypted) record data:",
@@ -2941,6 +2900,7 @@ ssl3_SendApplicationData(sslSocket *ss, const unsigned char *in,
ssl_GetXmitBufLock(ss);
}
toSend = PR_MIN(len - totalSent, MAX_FRAGMENT_LENGTH);
+
/*
* Note that the 0 epoch is OK because flags will never require
* its use, as guaranteed by the PORT_Assert above.
@@ -3077,7 +3037,9 @@ ssl3_HandleNoCertificate(sslSocket *ss)
(ss->opt.requireCertificate == SSL_REQUIRE_FIRST_HANDSHAKE))) {
PRFileDesc *lower;
- ss->sec.uncache(ss->sec.ci.sid);
+ if (!ss->opt.noCache) {
+ ss->sec.uncache(ss->sec.ci.sid);
+ }
SSL3_SendAlert(ss, alert_fatal, bad_certificate);
lower = ss->fd->lower;
@@ -3124,6 +3086,10 @@ SSL3_SendAlert(sslSocket *ss, SSL3AlertLevel level, SSL3AlertDescription desc)
{
PRUint8 bytes[2];
SECStatus rv;
+ PRBool needHsLock = !ssl_HaveSSL3HandshakeLock(ss);
+
+ /* Check that if I need the HS lock I also need the Xmit lock */
+ PORT_Assert(!needHsLock || !ssl_HaveXmitBufLock(ss));
SSL_TRC(3, ("%d: SSL3[%d]: send alert record, level=%d desc=%d",
SSL_GETPID(), ss->fd, level, desc));
@@ -3131,7 +3097,9 @@ SSL3_SendAlert(sslSocket *ss, SSL3AlertLevel level, SSL3AlertDescription desc)
bytes[0] = level;
bytes[1] = desc;
- ssl_GetSSL3HandshakeLock(ss);
+ if (needHsLock) {
+ ssl_GetSSL3HandshakeLock(ss);
+ }
if (level == alert_fatal) {
if (!ss->opt.noCache && ss->sec.ci.sid) {
ss->sec.uncache(ss->sec.ci.sid);
@@ -3149,7 +3117,13 @@ SSL3_SendAlert(sslSocket *ss, SSL3AlertLevel level, SSL3AlertDescription desc)
ss->ssl3.fatalAlertSent = PR_TRUE;
}
ssl_ReleaseXmitBufLock(ss);
- ssl_ReleaseSSL3HandshakeLock(ss);
+ if (needHsLock) {
+ ssl_ReleaseSSL3HandshakeLock(ss);
+ }
+ if (rv == SECSuccess && ss->alertSentCallback) {
+ SSLAlert alert = { level, desc };
+ ss->alertSentCallback(ss->fd, ss->alertSentCallbackArg, &alert);
+ }
return rv; /* error set by ssl3_FlushHandshake or ssl3_SendRecord */
}
@@ -3262,6 +3236,11 @@ ssl3_HandleAlert(sslSocket *ss, sslBuffer *buf)
SSL_TRC(5, ("%d: SSL3[%d] received alert, level = %d, description = %d",
SSL_GETPID(), ss->fd, level, desc));
+ if (ss->alertReceivedCallback) {
+ SSLAlert alert = { level, desc };
+ ss->alertReceivedCallback(ss->fd, ss->alertReceivedCallbackArg, &alert);
+ }
+
switch (desc) {
case close_notify:
ss->recvdCloseNotify = 1;
@@ -4088,11 +4067,9 @@ ssl3_InitHandshakeHashes(sslSocket *ss)
return SECSuccess;
}
-SECStatus
+void
ssl3_RestartHandshakeHashes(sslSocket *ss)
{
- SECStatus rv = SECSuccess;
-
SSL_TRC(30, ("%d: SSL3[%d]: reset handshake hashes",
SSL_GETPID(), ss->fd));
ss->ssl3.hs.hashType = handshake_hash_unknown;
@@ -4105,7 +4082,6 @@ ssl3_RestartHandshakeHashes(sslSocket *ss)
PK11_DestroyContext(ss->ssl3.hs.sha, PR_TRUE);
ss->ssl3.hs.sha = NULL;
}
- return rv;
}
/*
@@ -4243,7 +4219,7 @@ ssl3_AppendHandshakeNumber(sslSocket *ss, PRInt32 num, PRInt32 lenSize)
SECStatus
ssl3_AppendHandshakeVariable(
- sslSocket *ss, const SSL3Opaque *src, PRInt32 bytes, PRInt32 lenSize)
+ sslSocket *ss, const PRUint8 *src, PRInt32 bytes, PRInt32 lenSize)
{
SECStatus rv;
@@ -4330,7 +4306,7 @@ ssl3_AppendHandshakeHeader(sslSocket *ss, SSL3HandshakeType t, PRUint32 length)
* override the generic error code by setting another.
*/
SECStatus
-ssl3_ConsumeHandshake(sslSocket *ss, void *v, PRInt32 bytes, SSL3Opaque **b,
+ssl3_ConsumeHandshake(sslSocket *ss, void *v, PRUint32 bytes, PRUint8 **b,
PRUint32 *length)
{
PORT_Assert(ss->opt.noLocks || ssl_HaveRecvBufLock(ss));
@@ -4348,37 +4324,33 @@ ssl3_ConsumeHandshake(sslSocket *ss, void *v, PRInt32 bytes, SSL3Opaque **b,
/* Read up the next "bytes" number of bytes from the (decrypted) input
* stream "b" (which is *length bytes long), and interpret them as an
- * integer in network byte order. Returns the received value.
+ * integer in network byte order. Sets *num to the received value.
* Reduces *length by bytes. Advances *b by bytes.
*
- * Returns SECFailure (-1) on failure.
- * This value is indistinguishable from the equivalent received value.
- * Only positive numbers are to be received this way.
- * Thus, the largest value that may be sent this way is 0x7fffffff.
* On error, an alert has been sent, and a generic error code has been set.
*/
-PRInt32
-ssl3_ConsumeHandshakeNumber(sslSocket *ss, PRInt32 bytes, SSL3Opaque **b,
- PRUint32 *length)
+SECStatus
+ssl3_ConsumeHandshakeNumber(sslSocket *ss, PRUint32 *num, PRUint32 bytes,
+ PRUint8 **b, PRUint32 *length)
{
PRUint8 *buf = *b;
int i;
- PRInt32 num = 0;
PORT_Assert(ss->opt.noLocks || ssl_HaveRecvBufLock(ss));
PORT_Assert(ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss));
- PORT_Assert(bytes <= sizeof num);
- if ((PRUint32)bytes > *length) {
+ *num = 0;
+ if (bytes > *length || bytes > sizeof(*num)) {
return ssl3_DecodeError(ss);
}
PRINT_BUF(60, (ss, "consume bytes:", *b, bytes));
- for (i = 0; i < bytes; i++)
- num = (num << 8) + buf[i];
+ for (i = 0; i < bytes; i++) {
+ *num = (*num << 8) + buf[i];
+ }
*b += bytes;
*length -= bytes;
- return num;
+ return SECSuccess;
}
/* Read in two values from the incoming decrypted byte stream "b", which is
@@ -4396,21 +4368,22 @@ ssl3_ConsumeHandshakeNumber(sslSocket *ss, PRInt32 bytes, SSL3Opaque **b,
* point to the values in the buffer **b.
*/
SECStatus
-ssl3_ConsumeHandshakeVariable(sslSocket *ss, SECItem *i, PRInt32 bytes,
- SSL3Opaque **b, PRUint32 *length)
+ssl3_ConsumeHandshakeVariable(sslSocket *ss, SECItem *i, PRUint32 bytes,
+ PRUint8 **b, PRUint32 *length)
{
- PRInt32 count;
+ PRUint32 count;
+ SECStatus rv;
PORT_Assert(bytes <= 3);
i->len = 0;
i->data = NULL;
i->type = siBuffer;
- count = ssl3_ConsumeHandshakeNumber(ss, bytes, b, length);
- if (count < 0) { /* Can't test for SECSuccess here. */
+ rv = ssl3_ConsumeHandshakeNumber(ss, &count, bytes, b, length);
+ if (rv != SECSuccess) {
return SECFailure;
}
if (count > 0) {
- if ((PRUint32)count > *length) {
+ if (count > *length) {
return ssl3_DecodeError(ss);
}
i->data = *b;
@@ -4421,19 +4394,6 @@ ssl3_ConsumeHandshakeVariable(sslSocket *ss, SECItem *i, PRInt32 bytes,
return SECSuccess;
}
-/* Helper function to encode an unsigned integer into a buffer. */
-PRUint8 *
-ssl_EncodeUintX(PRUint64 value, unsigned int bytes, PRUint8 *to)
-{
- PRUint64 encoded;
-
- PORT_Assert(bytes > 0 && bytes <= sizeof(encoded));
-
- encoded = PR_htonll(value);
- memcpy(to, ((unsigned char *)(&encoded)) + (sizeof(encoded) - bytes), bytes);
- return to + bytes;
-}
-
/* ssl3_TLSHashAlgorithmToOID converts a TLS hash identifier into an OID value.
* If the hash is not recognised, SEC_OID_UNKNOWN is returned.
*
@@ -4678,13 +4638,14 @@ ssl_IsRsaPssSignatureScheme(SSLSignatureScheme scheme)
*
* See https://tools.ietf.org/html/rfc5246#section-7.4.1.4.1 */
SECStatus
-ssl_ConsumeSignatureScheme(sslSocket *ss, SSL3Opaque **b,
+ssl_ConsumeSignatureScheme(sslSocket *ss, PRUint8 **b,
PRUint32 *length, SSLSignatureScheme *out)
{
- PRInt32 tmp;
+ PRUint32 tmp;
+ SECStatus rv;
- tmp = ssl3_ConsumeHandshakeNumber(ss, 2, b, length);
- if (tmp < 0) {
+ rv = ssl3_ConsumeHandshakeNumber(ss, &tmp, 2, b, length);
+ if (rv != SECSuccess) {
return SECFailure; /* Error code set already. */
}
if (!ssl_IsSupportedSignatureScheme((SSLSignatureScheme)tmp)) {
@@ -4743,8 +4704,8 @@ ssl3_ComputeHandshakeHashes(sslSocket *ss,
SECStatus rv = SECSuccess;
PRBool isTLS = (PRBool)(spec->version > SSL_LIBRARY_VERSION_3_0);
unsigned int outLength;
- SSL3Opaque md5_inner[MAX_MAC_LENGTH];
- SSL3Opaque sha_inner[MAX_MAC_LENGTH];
+ PRUint8 md5_inner[MAX_MAC_LENGTH];
+ PRUint8 sha_inner[MAX_MAC_LENGTH];
PORT_Assert(ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss));
if (ss->ssl3.hs.hashType == handshake_hash_unknown) {
@@ -4990,7 +4951,6 @@ ssl3_SendClientHello(sslSocket *ss, sslClientHelloType type)
PRBool isTLS = PR_FALSE;
PRBool requestingResume = PR_FALSE, fallbackSCSV = PR_FALSE;
PRInt32 total_exten_len = 0;
- unsigned paddingExtensionLen;
unsigned numCompressionMethods;
PRUint16 version;
PRInt32 flags;
@@ -5013,15 +4973,8 @@ ssl3_SendClientHello(sslSocket *ss, sslClientHelloType type)
if (ss->ssl3.hs.helloRetry) {
PORT_Assert(type == client_hello_retry);
} else {
- rv = ssl3_InitState(ss);
- if (rv != SECSuccess) {
- return rv; /* ssl3_InitState has set the error code. */
- }
-
- rv = ssl3_RestartHandshakeHashes(ss);
- if (rv != SECSuccess) {
- return rv;
- }
+ ssl3_InitState(ss);
+ ssl3_RestartHandshakeHashes(ss);
}
/* These must be reset every handshake. */
@@ -5293,19 +5246,12 @@ ssl3_SendClientHello(sslSocket *ss, sslClientHelloType type)
length += 1 + ss->ssl3.hs.cookie.len;
}
- /* A padding extension may be included to ensure that the record containing
- * the ClientHello doesn't have a length between 256 and 511 bytes
- * (inclusive). Initial, ClientHello records with such lengths trigger bugs
- * in F5 devices.
- *
- * This is not done for DTLS, for renegotiation, or when there are no
- * extensions. */
- if (!IS_DTLS(ss) && isTLS && !ss->firstHsDone && total_exten_len) {
- paddingExtensionLen = ssl3_CalculatePaddingExtensionLength(length);
- total_exten_len += paddingExtensionLen;
- length += paddingExtensionLen;
- } else {
- paddingExtensionLen = 0;
+ if (total_exten_len > 0) {
+ ssl3_CalculatePaddingExtLen(ss, length);
+ if (ss->xtnData.paddingLen) {
+ total_exten_len += 4 + ss->xtnData.paddingLen;
+ length += 4 + ss->xtnData.paddingLen;
+ }
}
rv = ssl3_AppendHandshakeHeader(ss, client_hello, length);
@@ -5476,15 +5422,6 @@ ssl3_SendClientHello(sslSocket *ss, sslClientHelloType type)
return rv; /* err set by AppendHandshake. */
}
- extLen = ssl3_AppendPaddingExtension(ss, paddingExtensionLen, maxBytes);
- if (extLen < 0) {
- if (sid->u.ssl3.lock) {
- PR_RWLock_Unlock(sid->u.ssl3.lock);
- }
- return SECFailure;
- }
- maxBytes -= extLen;
-
extLen = ssl3_CallHelloExtensionSenders(ss, PR_TRUE, maxBytes, NULL);
if (extLen < 0) {
if (sid->u.ssl3.lock) {
@@ -5579,8 +5516,6 @@ ssl3_HandleHelloRequest(sslSocket *ss)
return rv;
}
-#define UNKNOWN_WRAP_MECHANISM 0x7fffffff
-
static const CK_MECHANISM_TYPE wrapMechanismList[SSL_NUM_WRAP_MECHS] = {
CKM_DES3_ECB,
CKM_CAST5_ECB,
@@ -5596,27 +5531,58 @@ static const CK_MECHANISM_TYPE wrapMechanismList[SSL_NUM_WRAP_MECHS] = {
CKM_SKIPJACK_CBC64,
CKM_AES_ECB,
CKM_CAMELLIA_ECB,
- CKM_SEED_ECB,
- UNKNOWN_WRAP_MECHANISM
+ CKM_SEED_ECB
};
-static int
-ssl_FindIndexByWrapMechanism(CK_MECHANISM_TYPE mech)
+static SECStatus
+ssl_FindIndexByWrapMechanism(CK_MECHANISM_TYPE mech, unsigned int *wrapMechIndex)
{
- const CK_MECHANISM_TYPE *pMech = wrapMechanismList;
+ unsigned int i;
+ for (i = 0; i < SSL_NUM_WRAP_MECHS; ++i) {
+ if (wrapMechanismList[i] == mech) {
+ *wrapMechIndex = i;
+ return SECSuccess;
+ }
+ }
+ PORT_Assert(0);
+ PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
+ return SECFailure;
+}
- while (mech != *pMech && *pMech != UNKNOWN_WRAP_MECHANISM) {
- ++pMech;
+/* Each process sharing the server session ID cache has its own array of SymKey
+ * pointers for the symmetric wrapping keys that are used to wrap the master
+ * secrets. There is one key for each authentication type. These Symkeys
+ * correspond to the wrapped SymKeys kept in the server session cache.
+ */
+const SSLAuthType ssl_wrap_key_auth_type[SSL_NUM_WRAP_KEYS] = {
+ ssl_auth_rsa_decrypt,
+ ssl_auth_rsa_sign,
+ ssl_auth_rsa_pss,
+ ssl_auth_ecdsa,
+ ssl_auth_ecdh_rsa,
+ ssl_auth_ecdh_ecdsa
+};
+
+static SECStatus
+ssl_FindIndexByWrapKey(const sslServerCert *serverCert, unsigned int *wrapKeyIndex)
+{
+ unsigned int i;
+ for (i = 0; i < SSL_NUM_WRAP_KEYS; ++i) {
+ if (SSL_CERT_IS(serverCert, ssl_wrap_key_auth_type[i])) {
+ *wrapKeyIndex = i;
+ return SECSuccess;
+ }
}
- return (*pMech == UNKNOWN_WRAP_MECHANISM) ? -1
- : (pMech - wrapMechanismList);
+ /* Can't assert here because we still get people using DSA certificates. */
+ PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
+ return SECFailure;
}
static PK11SymKey *
ssl_UnwrapSymWrappingKey(
SSLWrappedSymWrappingKey *pWswk,
SECKEYPrivateKey *svrPrivKey,
- SSLAuthType authType,
+ unsigned int wrapKeyIndex,
CK_MECHANISM_TYPE masterWrapMech,
void *pwArg)
{
@@ -5628,9 +5594,9 @@ ssl_UnwrapSymWrappingKey(
/* found the wrapping key on disk. */
PORT_Assert(pWswk->symWrapMechanism == masterWrapMech);
- PORT_Assert(pWswk->authType == authType);
+ PORT_Assert(pWswk->wrapKeyIndex == wrapKeyIndex);
if (pWswk->symWrapMechanism != masterWrapMech ||
- pWswk->authType != authType) {
+ pWswk->wrapKeyIndex != wrapKeyIndex) {
goto loser;
}
wrappedKey.type = siBuffer;
@@ -5638,7 +5604,7 @@ ssl_UnwrapSymWrappingKey(
wrappedKey.len = pWswk->wrappedSymKeyLen;
PORT_Assert(wrappedKey.len <= sizeof pWswk->wrappedSymmetricWrappingkey);
- switch (authType) {
+ switch (ssl_wrap_key_auth_type[wrapKeyIndex]) {
case ssl_auth_rsa_decrypt:
case ssl_auth_rsa_sign: /* bad: see Bug 1248320 */
@@ -5711,14 +5677,8 @@ loser:
return unwrappedWrappingKey;
}
-/* Each process sharing the server session ID cache has its own array of SymKey
- * pointers for the symmetric wrapping keys that are used to wrap the master
- * secrets. There is one key for each authentication type. These Symkeys
- * correspond to the wrapped SymKeys kept in the server session cache.
- */
-
typedef struct {
- PK11SymKey *symWrapKey[ssl_auth_size];
+ PK11SymKey *symWrapKey[SSL_NUM_WRAP_KEYS];
} ssl3SymWrapKey;
static PZLock *symWrapKeysLock = NULL;
@@ -5746,7 +5706,7 @@ SSL3_ShutdownServerCache(void)
PZ_Lock(symWrapKeysLock);
/* get rid of all symWrapKeys */
for (i = 0; i < SSL_NUM_WRAP_MECHS; ++i) {
- for (j = 0; j < ssl_auth_size; ++j) {
+ for (j = 0; j < SSL_NUM_WRAP_KEYS; ++j) {
PK11SymKey **pSymWrapKey;
pSymWrapKey = &symWrapKeys[i].symWrapKey[j];
if (*pSymWrapKey) {
@@ -5780,7 +5740,6 @@ ssl_InitSymWrapKeysLock(void)
PK11SymKey *
ssl3_GetWrappingKey(sslSocket *ss,
PK11SlotInfo *masterSecretSlot,
- const sslServerCert *serverCert,
CK_MECHANISM_TYPE masterWrapMech,
void *pwArg)
{
@@ -5791,7 +5750,8 @@ ssl3_GetWrappingKey(sslSocket *ss,
PK11SymKey **pSymWrapKey;
CK_MECHANISM_TYPE asymWrapMechanism = CKM_INVALID_MECHANISM;
int length;
- int symWrapMechIndex;
+ unsigned int wrapMechIndex;
+ unsigned int wrapKeyIndex;
SECStatus rv;
SECItem wrappedKey;
SSLWrappedSymWrappingKey wswk;
@@ -5799,6 +5759,7 @@ ssl3_GetWrappingKey(sslSocket *ss,
SECKEYPublicKey *pubWrapKey = NULL;
SECKEYPrivateKey *privWrapKey = NULL;
ECCWrappedKeyInfo *ecWrapped;
+ const sslServerCert *serverCert = ss->sec.serverCert;
PORT_Assert(serverCert);
PORT_Assert(serverCert->serverKeyPair);
@@ -5810,15 +5771,18 @@ ssl3_GetWrappingKey(sslSocket *ss,
PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
return NULL; /* hmm */
}
- authType = serverCert->certType.authType;
- svrPrivKey = serverCert->serverKeyPair->privKey;
- symWrapMechIndex = ssl_FindIndexByWrapMechanism(masterWrapMech);
- PORT_Assert(symWrapMechIndex >= 0);
- if (symWrapMechIndex < 0)
+ rv = ssl_FindIndexByWrapKey(serverCert, &wrapKeyIndex);
+ if (rv != SECSuccess)
+ return NULL; /* unusable wrapping key. */
+
+ rv = ssl_FindIndexByWrapMechanism(masterWrapMech, &wrapMechIndex);
+ if (rv != SECSuccess)
return NULL; /* invalid masterWrapMech. */
- pSymWrapKey = &symWrapKeys[symWrapMechIndex].symWrapKey[authType];
+ authType = ssl_wrap_key_auth_type[wrapKeyIndex];
+ svrPrivKey = serverCert->serverKeyPair->privKey;
+ pSymWrapKey = &symWrapKeys[wrapMechIndex].symWrapKey[wrapKeyIndex];
ssl_InitSessionCacheLocks(PR_TRUE);
@@ -5837,10 +5801,11 @@ ssl3_GetWrappingKey(sslSocket *ss,
/* Try to get wrapped SymWrapping key out of the (disk) cache. */
/* Following call fills in wswk on success. */
- if (ssl_GetWrappingKey(symWrapMechIndex, authType, &wswk)) {
+ rv = ssl_GetWrappingKey(wrapMechIndex, wrapKeyIndex, &wswk);
+ if (rv == SECSuccess) {
/* found the wrapped sym wrapping key on disk. */
unwrappedWrappingKey =
- ssl_UnwrapSymWrappingKey(&wswk, svrPrivKey, authType,
+ ssl_UnwrapSymWrappingKey(&wswk, svrPrivKey, wrapKeyIndex,
masterWrapMech, pwArg);
if (unwrappedWrappingKey) {
goto install;
@@ -5989,9 +5954,9 @@ ssl3_GetWrappingKey(sslSocket *ss,
PORT_Assert(asymWrapMechanism != CKM_INVALID_MECHANISM);
wswk.symWrapMechanism = masterWrapMech;
- wswk.symWrapMechIndex = symWrapMechIndex;
wswk.asymWrapMechanism = asymWrapMechanism;
- wswk.authType = authType;
+ wswk.wrapMechIndex = wrapMechIndex;
+ wswk.wrapKeyIndex = wrapKeyIndex;
wswk.wrappedSymKeyLen = wrappedKey.len;
/* put it on disk. */
@@ -5999,7 +5964,8 @@ ssl3_GetWrappingKey(sslSocket *ss,
* then abandon the value we just computed and
* use the one we got from the disk.
*/
- if (ssl_SetWrappingKey(&wswk)) {
+ rv = ssl_SetWrappingKey(&wswk);
+ if (rv == SECSuccess) {
/* somebody beat us to it. The original contents of our wswk
* has been replaced with the content on disk. Now, discard
* the key we just created and unwrap this new one.
@@ -6007,7 +5973,7 @@ ssl3_GetWrappingKey(sslSocket *ss,
PK11_FreeSymKey(unwrappedWrappingKey);
unwrappedWrappingKey =
- ssl_UnwrapSymWrappingKey(&wswk, svrPrivKey, authType,
+ ssl_UnwrapSymWrappingKey(&wswk, svrPrivKey, wrapKeyIndex,
masterWrapMech, pwArg);
}
@@ -6411,6 +6377,33 @@ ssl_PickSignatureScheme(sslSocket *ss,
return SECFailure;
}
+static SECStatus
+ssl_PickFallbackSignatureScheme(sslSocket *ss, SECKEYPublicKey *pubKey)
+{
+ PRBool isTLS12 = ss->version >= SSL_LIBRARY_VERSION_TLS_1_2;
+
+ switch (SECKEY_GetPublicKeyType(pubKey)) {
+ case rsaKey:
+ if (isTLS12) {
+ ss->ssl3.hs.signatureScheme = ssl_sig_rsa_pkcs1_sha1;
+ } else {
+ ss->ssl3.hs.signatureScheme = ssl_sig_rsa_pkcs1_sha1md5;
+ }
+ break;
+ case ecKey:
+ ss->ssl3.hs.signatureScheme = ssl_sig_ecdsa_sha1;
+ break;
+ case dsaKey:
+ ss->ssl3.hs.signatureScheme = ssl_sig_dsa_sha1;
+ break;
+ default:
+ PORT_Assert(0);
+ PORT_SetError(SEC_ERROR_INVALID_KEY);
+ return SECFailure;
+ }
+ return SECSuccess;
+}
+
/* ssl3_PickServerSignatureScheme selects a signature scheme for signing the
* handshake. Most of this is determined by the key pair we are using.
* Prior to TLS 1.2, the MD5/SHA1 combination is always used. With TLS 1.2, a
@@ -6424,26 +6417,7 @@ ssl3_PickServerSignatureScheme(sslSocket *ss)
if (!isTLS12 || !ssl3_ExtensionNegotiated(ss, ssl_signature_algorithms_xtn)) {
/* If the client didn't provide any signature_algorithms extension then
* we can assume that they support SHA-1: RFC5246, Section 7.4.1.4.1. */
- switch (SECKEY_GetPublicKeyType(keyPair->pubKey)) {
- case rsaKey:
- if (isTLS12) {
- ss->ssl3.hs.signatureScheme = ssl_sig_rsa_pkcs1_sha1;
- } else {
- ss->ssl3.hs.signatureScheme = ssl_sig_rsa_pkcs1_sha1md5;
- }
- break;
- case ecKey:
- ss->ssl3.hs.signatureScheme = ssl_sig_ecdsa_sha1;
- break;
- case dsaKey:
- ss->ssl3.hs.signatureScheme = ssl_sig_dsa_sha1;
- break;
- default:
- PORT_Assert(0);
- PORT_SetError(SEC_ERROR_INVALID_KEY);
- return SECFailure;
- }
- return SECSuccess;
+ return ssl_PickFallbackSignatureScheme(ss, keyPair->pubKey);
}
/* Sets error code, if needed. */
@@ -6461,9 +6435,21 @@ ssl_PickClientSignatureScheme(sslSocket *ss, const SSLSignatureScheme *schemes,
SECKEYPublicKey *pubKey;
SECStatus rv;
+ PRBool isTLS13 = (PRBool)ss->version >= SSL_LIBRARY_VERSION_TLS_1_3;
pubKey = CERT_ExtractPublicKey(ss->ssl3.clientCertificate);
PORT_Assert(pubKey);
- if (ss->version < SSL_LIBRARY_VERSION_TLS_1_3 &&
+
+ if (!isTLS13 && numSchemes == 0) {
+ /* If the server didn't provide any signature algorithms
+ * then let's assume they support SHA-1. */
+ rv = ssl_PickFallbackSignatureScheme(ss, pubKey);
+ SECKEY_DestroyPublicKey(pubKey);
+ return rv;
+ }
+
+ PORT_Assert(schemes && numSchemes > 0);
+
+ if (!isTLS13 &&
(SECKEY_GetPublicKeyType(pubKey) == rsaKey ||
SECKEY_GetPublicKeyType(pubKey) == dsaKey) &&
SECKEY_PublicKeyStrengthInBits(pubKey) <= 1024) {
@@ -6604,9 +6590,9 @@ ssl3_SetCipherSuite(sslSocket *ss, ssl3CipherSuite chosenSuite,
* Caller must hold Handshake and RecvBuf locks.
*/
static SECStatus
-ssl3_HandleServerHello(sslSocket *ss, SSL3Opaque *b, PRUint32 length)
+ssl3_HandleServerHello(sslSocket *ss, PRUint8 *b, PRUint32 length)
{
- PRInt32 temp; /* allow for consume number failure */
+ PRUint32 temp;
PRBool suite_found = PR_FALSE;
int i;
int errCode = SSL_ERROR_RX_MALFORMED_SERVER_HELLO;
@@ -6649,11 +6635,21 @@ ssl3_HandleServerHello(sslSocket *ss, SSL3Opaque *b, PRUint32 length)
goto loser; /* alert has been sent */
}
- /* We got a HelloRetryRequest, but the server didn't pick 1.3. Scream. */
- if (ss->ssl3.hs.helloRetry && ss->version < SSL_LIBRARY_VERSION_TLS_1_3) {
- desc = illegal_parameter;
- errCode = SSL_ERROR_RX_MALFORMED_SERVER_HELLO;
- goto alert_loser;
+ /* The server didn't pick 1.3 although we either received a
+ * HelloRetryRequest, or we prepared to send early app data. */
+ if (ss->version < SSL_LIBRARY_VERSION_TLS_1_3) {
+ if (ss->ssl3.hs.helloRetry) {
+ /* SSL3_SendAlert() will uncache the SID. */
+ desc = illegal_parameter;
+ errCode = SSL_ERROR_RX_MALFORMED_SERVER_HELLO;
+ goto alert_loser;
+ }
+ if (ss->ssl3.hs.zeroRttState == ssl_0rtt_sent) {
+ /* SSL3_SendAlert() will uncache the SID. */
+ desc = illegal_parameter;
+ errCode = SSL_ERROR_DOWNGRADE_WITH_EARLY_DATA;
+ goto alert_loser;
+ }
}
/* Check that the server negotiated the same version as it did
@@ -6721,8 +6717,8 @@ ssl3_HandleServerHello(sslSocket *ss, SSL3Opaque *b, PRUint32 length)
}
/* find selected cipher suite in our list. */
- temp = ssl3_ConsumeHandshakeNumber(ss, 2, &b, &length);
- if (temp < 0) {
+ rv = ssl3_ConsumeHandshakeNumber(ss, &temp, 2, &b, &length);
+ if (rv != SECSuccess) {
goto loser; /* alert has been sent */
}
i = ssl3_config_match_init(ss);
@@ -6767,8 +6763,8 @@ ssl3_HandleServerHello(sslSocket *ss, SSL3Opaque *b, PRUint32 length)
if (ss->version < SSL_LIBRARY_VERSION_TLS_1_3) {
/* find selected compression method in our list. */
- temp = ssl3_ConsumeHandshakeNumber(ss, 1, &b, &length);
- if (temp < 0) {
+ rv = ssl3_ConsumeHandshakeNumber(ss, &temp, 1, &b, &length);
+ if (rv != SECSuccess) {
goto loser; /* alert has been sent */
}
suite_found = PR_FALSE;
@@ -7010,6 +7006,19 @@ ssl3_HandleServerHelloPart2(sslSocket *ss, const SECItem *sidBytes,
else
SSL_AtomicIncrementLong(&ssl3stats.hsh_sid_cache_misses);
+ /* We tried to resume a 1.3 session but the server negotiated 1.2. */
+ if (ss->statelessResume) {
+ PORT_Assert(sid->version == SSL_LIBRARY_VERSION_TLS_1_3);
+ PORT_Assert(ss->ssl3.hs.currentSecret);
+
+ /* Reset resumption state, only used by 1.3 code. */
+ ss->statelessResume = PR_FALSE;
+
+ /* Clear TLS 1.3 early data traffic key. */
+ PK11_FreeSymKey(ss->ssl3.hs.currentSecret);
+ ss->ssl3.hs.currentSecret = NULL;
+ }
+
/* throw the old one away */
sid->u.ssl3.keys.resumable = PR_FALSE;
ss->sec.uncache(sid);
@@ -7062,7 +7071,7 @@ loser:
}
static SECStatus
-ssl_HandleDHServerKeyExchange(sslSocket *ss, SSL3Opaque *b, PRUint32 length)
+ssl_HandleDHServerKeyExchange(sslSocket *ss, PRUint8 *b, PRUint32 length)
{
SECStatus rv;
int errCode = SSL_ERROR_RX_MALFORMED_SERVER_KEY_EXCH;
@@ -7222,7 +7231,7 @@ loser:
* Caller must hold Handshake and RecvBuf locks.
*/
static SECStatus
-ssl3_HandleServerKeyExchange(sslSocket *ss, SSL3Opaque *b, PRUint32 length)
+ssl3_HandleServerKeyExchange(sslSocket *ss, PRUint8 *b, PRUint32 length)
{
SECStatus rv;
@@ -7273,19 +7282,20 @@ typedef struct dnameNode {
* tls13_HandleCertificateRequest
*/
SECStatus
-ssl3_ParseCertificateRequestCAs(sslSocket *ss, SSL3Opaque **b, PRUint32 *length,
+ssl3_ParseCertificateRequestCAs(sslSocket *ss, PRUint8 **b, PRUint32 *length,
PLArenaPool *arena, CERTDistNames *ca_list)
{
- PRInt32 remaining;
+ PRUint32 remaining;
int nnames = 0;
dnameNode *node;
+ SECStatus rv;
int i;
- remaining = ssl3_ConsumeHandshakeNumber(ss, 2, b, length);
- if (remaining < 0)
+ rv = ssl3_ConsumeHandshakeNumber(ss, &remaining, 2, b, length);
+ if (rv != SECSuccess)
return SECFailure; /* malformed, alert has been sent */
- if ((PRUint32)remaining > *length)
+ if (remaining > *length)
goto alert_loser;
ca_list->head = node = PORT_ArenaZNew(arena, dnameNode);
@@ -7293,19 +7303,19 @@ ssl3_ParseCertificateRequestCAs(sslSocket *ss, SSL3Opaque **b, PRUint32 *length,
goto no_mem;
while (remaining > 0) {
- PRInt32 len;
+ PRUint32 len;
if (remaining < 2)
goto alert_loser; /* malformed */
- node->name.len = len = ssl3_ConsumeHandshakeNumber(ss, 2, b, length);
- if (len <= 0)
+ rv = ssl3_ConsumeHandshakeNumber(ss, &len, 2, b, length);
+ if (rv != SECSuccess)
return SECFailure; /* malformed, alert has been sent */
-
- remaining -= 2;
- if (remaining < len)
+ if (len == 0 || remaining < len + 2)
goto alert_loser; /* malformed */
+ remaining -= 2;
+ node->name.len = len;
node->name.data = *b;
*b += len;
*length -= len;
@@ -7353,7 +7363,7 @@ ssl_ParseSignatureSchemes(const sslSocket *ss, PLArenaPool *arena,
{
SECStatus rv;
SECItem buf;
- SSLSignatureScheme *schemes;
+ SSLSignatureScheme *schemes = NULL;
unsigned int numSchemes = 0;
unsigned int max;
@@ -7361,12 +7371,17 @@ ssl_ParseSignatureSchemes(const sslSocket *ss, PLArenaPool *arena,
if (rv != SECSuccess) {
return SECFailure;
}
- /* An empty or odd-length value is invalid. */
- if (buf.len == 0 || (buf.len & 1) != 0) {
+ /* An odd-length value is invalid. */
+ if ((buf.len & 1) != 0) {
ssl3_ExtSendAlert(ss, alert_fatal, decode_error);
return SECFailure;
}
+ /* Let the caller decide whether to alert here. */
+ if (buf.len == 0) {
+ goto done;
+ }
+
/* Limit the number of schemes we read. */
max = PR_MIN(buf.len / 2, MAX_SIGNATURE_SCHEMES);
@@ -7381,9 +7396,9 @@ ssl_ParseSignatureSchemes(const sslSocket *ss, PLArenaPool *arena,
}
for (; max; --max) {
- PRInt32 tmp;
- tmp = ssl3_ExtConsumeHandshakeNumber(ss, 2, &buf.data, &buf.len);
- if (tmp < 0) {
+ PRUint32 tmp;
+ rv = ssl3_ExtConsumeHandshakeNumber(ss, &tmp, 2, &buf.data, &buf.len);
+ if (rv != SECSuccess) {
PORT_Assert(0);
PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
return SECFailure;
@@ -7400,6 +7415,7 @@ ssl_ParseSignatureSchemes(const sslSocket *ss, PLArenaPool *arena,
schemes = NULL;
}
+done:
*schemesOut = schemes;
*numSchemesOut = numSchemes;
return SECSuccess;
@@ -7410,7 +7426,7 @@ ssl_ParseSignatureSchemes(const sslSocket *ss, PLArenaPool *arena,
* Caller must hold Handshake and RecvBuf locks.
*/
static SECStatus
-ssl3_HandleCertificateRequest(sslSocket *ss, SSL3Opaque *b, PRUint32 length)
+ssl3_HandleCertificateRequest(sslSocket *ss, PRUint8 *b, PRUint32 length)
{
PLArenaPool *arena = NULL;
PRBool isTLS = PR_FALSE;
@@ -8227,19 +8243,17 @@ ssl3_SelectServerCert(sslSocket *ss)
cursor != &ss->serverCerts;
cursor = PR_NEXT_LINK(cursor)) {
sslServerCert *cert = (sslServerCert *)cursor;
- if (cert->certType.authType != kea_def->authKeyType) {
+ if (!SSL_CERT_IS(cert, kea_def->authKeyType)) {
continue;
}
- if ((cert->certType.authType == ssl_auth_ecdsa ||
- cert->certType.authType == ssl_auth_ecdh_rsa ||
- cert->certType.authType == ssl_auth_ecdh_ecdsa) &&
- !ssl_NamedGroupEnabled(ss, cert->certType.namedCurve)) {
+ if (SSL_CERT_IS_EC(cert) &&
+ !ssl_NamedGroupEnabled(ss, cert->namedCurve)) {
continue;
}
/* Found one. */
ss->sec.serverCert = cert;
- ss->sec.authType = cert->certType.authType;
+ ss->sec.authType = kea_def->authKeyType;
ss->sec.authKeyBits = cert->serverKeyBits;
/* Don't pick a signature scheme if we aren't going to use it. */
@@ -8258,10 +8272,10 @@ ssl3_SelectServerCert(sslSocket *ss)
* Caller must hold Handshake and RecvBuf locks.
*/
static SECStatus
-ssl3_HandleClientHello(sslSocket *ss, SSL3Opaque *b, PRUint32 length)
+ssl3_HandleClientHello(sslSocket *ss, PRUint8 *b, PRUint32 length)
{
sslSessionID *sid = NULL;
- PRInt32 tmp;
+ PRUint32 tmp;
unsigned int i;
SECStatus rv;
int errCode = SSL_ERROR_RX_MALFORMED_CLIENT_HELLO;
@@ -8321,8 +8335,8 @@ ssl3_HandleClientHello(sslSocket *ss, SSL3Opaque *b, PRUint32 length)
dtls_RehandshakeCleanup(ss);
}
- tmp = ssl3_ConsumeHandshakeNumber(ss, 2, &b, &length);
- if (tmp < 0)
+ rv = ssl3_ConsumeHandshakeNumber(ss, &tmp, 2, &b, &length);
+ if (rv != SECSuccess)
goto loser; /* malformed, alert already sent */
/* Translate the version. */
@@ -8375,9 +8389,9 @@ ssl3_HandleClientHello(sslSocket *ss, SSL3Opaque *b, PRUint32 length)
if (length) {
/* Get length of hello extensions */
- PRInt32 extension_length;
- extension_length = ssl3_ConsumeHandshakeNumber(ss, 2, &b, &length);
- if (extension_length < 0) {
+ PRUint32 extension_length;
+ rv = ssl3_ConsumeHandshakeNumber(ss, &extension_length, 2, &b, &length);
+ if (rv != SECSuccess) {
goto loser; /* alert already sent */
}
if (extension_length != length) {
@@ -8479,7 +8493,7 @@ ssl3_HandleClientHello(sslSocket *ss, SSL3Opaque *b, PRUint32 length)
/* If the ClientHello version is less than our maximum version, check for a
* TLS_FALLBACK_SCSV and reject the connection if found. */
- if (ss->vrange.max > ss->clientHelloVersion) {
+ if (ss->vrange.max > ss->version) {
for (i = 0; i + 1 < suites.len; i += 2) {
PRUint16 suite_i = (suites.data[i] << 8) | suites.data[i + 1];
if (suite_i != TLS_FALLBACK_SCSV)
@@ -8505,7 +8519,7 @@ ssl3_HandleClientHello(sslSocket *ss, SSL3Opaque *b, PRUint32 length)
for (i = 0; i + 1 < suites.len; i += 2) {
PRUint16 suite_i = (suites.data[i] << 8) | suites.data[i + 1];
if (suite_i == TLS_EMPTY_RENEGOTIATION_INFO_SCSV) {
- SSL3Opaque *b2 = (SSL3Opaque *)emptyRIext;
+ PRUint8 *b2 = (PRUint8 *)emptyRIext;
PRUint32 L2 = sizeof emptyRIext;
(void)ssl3_HandleExtensions(ss, &b2, &L2, client_hello);
break;
@@ -8763,7 +8777,6 @@ compression_found:
do {
ssl3CipherSpec *pwSpec;
SECItem wrappedMS; /* wrapped key */
- const sslServerCert *serverCert;
if (sid->version != ss->version ||
sid->u.ssl3.cipherSuite != ss->ssl3.hs.cipher_suite ||
@@ -8771,8 +8784,13 @@ compression_found:
break; /* not an error */
}
- serverCert = ssl_FindServerCert(ss, &sid->certType);
- if (!serverCert || !serverCert->serverCert) {
+ /* server sids don't remember the server cert we previously sent,
+ ** but they do remember the slot we originally used, so we
+ ** can locate it again, provided that the current ssl socket
+ ** has had its server certs configured the same as the previous one.
+ */
+ ss->sec.serverCert = ssl_FindServerCert(ss, sid->authType, sid->namedCurve);
+ if (!ss->sec.serverCert || !ss->sec.serverCert->serverCert) {
/* A compatible certificate must not have been configured. It
* might not be the same certificate, but we only find that out
* when the ticket fails to decrypt. */
@@ -8820,7 +8838,7 @@ compression_found:
PK11SymKey *wrapKey; /* wrapping key */
CK_FLAGS keyFlags = 0;
- wrapKey = ssl3_GetWrappingKey(ss, NULL, serverCert,
+ wrapKey = ssl3_GetWrappingKey(ss, NULL,
sid->u.ssl3.masterWrapMech,
ss->pkcs11PinArg);
if (!wrapKey) {
@@ -8879,13 +8897,8 @@ compression_found:
ss->sec.keaType = sid->keaType;
ss->sec.keaKeyBits = sid->keaKeyBits;
- /* server sids don't remember the server cert we previously sent,
- ** but they do remember the slot we originally used, so we
- ** can locate it again, provided that the current ssl socket
- ** has had its server certs configured the same as the previous one.
- */
- ss->sec.serverCert = serverCert;
- ss->sec.localCert = CERT_DupCertificate(serverCert->serverCert);
+ ss->sec.localCert =
+ CERT_DupCertificate(ss->sec.serverCert->serverCert);
/* Copy cached name in to pending spec */
if (sid != NULL &&
@@ -9077,16 +9090,8 @@ ssl3_HandleV2ClientHello(sslSocket *ss, unsigned char *buffer, int length,
goto loser;
}
- rv = ssl3_InitState(ss);
- if (rv != SECSuccess) {
- ssl_ReleaseSSL3HandshakeLock(ss);
- return rv; /* ssl3_InitState has set the error code. */
- }
- rv = ssl3_RestartHandshakeHashes(ss);
- if (rv != SECSuccess) {
- ssl_ReleaseSSL3HandshakeLock(ss);
- return rv;
- }
+ ssl3_InitState(ss);
+ ssl3_RestartHandshakeHashes(ss);
if (ss->ssl3.hs.ws != wait_client_hello) {
desc = unexpected_message;
@@ -9202,7 +9207,7 @@ suite_found:
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 == TLS_EMPTY_RENEGOTIATION_INFO_SCSV) {
- SSL3Opaque *b2 = (SSL3Opaque *)emptyRIext;
+ PRUint8 *b2 = (PRUint8 *)emptyRIext;
PRUint32 L2 = sizeof emptyRIext;
(void)ssl3_HandleExtensions(ss, &b2, &L2, client_hello);
break;
@@ -9603,34 +9608,6 @@ ssl3_EncodeSigAlgs(const sslSocket *ss, PRUint8 *buf, unsigned maxLen, PRUint32
return SECSuccess;
}
-void
-ssl3_GetCertificateRequestCAs(sslSocket *ss, int *calen, SECItem **names,
- int *nnames)
-{
- SECItem *name;
- CERTDistNames *ca_list;
- int i;
-
- *calen = 0;
- *names = NULL;
- *nnames = 0;
-
- /* ssl3.ca_list is initialized to NULL, and never changed. */
- ca_list = ss->ssl3.ca_list;
- if (!ca_list) {
- ca_list = ssl3_server_ca_list;
- }
-
- if (ca_list != NULL) {
- *names = ca_list->names;
- *nnames = ca_list->nnames;
- }
-
- for (i = 0, name = *names; i < *nnames; i++, name++) {
- *calen += 2 + name->len;
- }
-}
-
static SECStatus
ssl3_SendCertificateRequest(sslSocket *ss)
{
@@ -9639,8 +9616,8 @@ ssl3_SendCertificateRequest(sslSocket *ss)
SECStatus rv;
int length;
SECItem *names;
- int calen;
- int nnames;
+ unsigned int calen;
+ unsigned int nnames;
SECItem *name;
int i;
int certTypesLength;
@@ -9655,7 +9632,10 @@ ssl3_SendCertificateRequest(sslSocket *ss)
isTLS12 = (PRBool)(ss->ssl3.pwSpec->version >= SSL_LIBRARY_VERSION_TLS_1_2);
- ssl3_GetCertificateRequestCAs(ss, &calen, &names, &nnames);
+ rv = ssl_GetCertificateRequestCAs(ss, &calen, &names, &nnames);
+ if (rv != SECSuccess) {
+ return rv;
+ }
certTypes = certificate_types;
certTypesLength = sizeof certificate_types;
@@ -9723,7 +9703,7 @@ ssl3_SendServerHelloDone(sslSocket *ss)
* Caller must hold Handshake and RecvBuf locks.
*/
static SECStatus
-ssl3_HandleCertificateVerify(sslSocket *ss, SSL3Opaque *b, PRUint32 length,
+ssl3_HandleCertificateVerify(sslSocket *ss, PRUint8 *b, PRUint32 length,
SSL3Hashes *hashes)
{
SECItem signed_hash = { siBuffer, NULL, 0 };
@@ -9741,17 +9721,15 @@ ssl3_HandleCertificateVerify(sslSocket *ss, SSL3Opaque *b, PRUint32 length,
PORT_Assert(ss->opt.noLocks || ssl_HaveRecvBufLock(ss));
PORT_Assert(ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss));
- /* TLS 1.3 is handled by tls13_HandleCertificateVerify */
- PORT_Assert(ss->ssl3.prSpec->version <= SSL_LIBRARY_VERSION_TLS_1_2);
-
- isTLS = (PRBool)(ss->ssl3.prSpec->version > SSL_LIBRARY_VERSION_3_0);
-
if (ss->ssl3.hs.ws != wait_cert_verify) {
desc = unexpected_message;
errCode = SSL_ERROR_RX_UNEXPECTED_CERT_VERIFY;
goto alert_loser;
}
+ /* TLS 1.3 is handled by tls13_HandleCertificateVerify */
+ PORT_Assert(ss->ssl3.prSpec->version <= SSL_LIBRARY_VERSION_TLS_1_2);
+
if (!hashes) {
PORT_Assert(0);
desc = internal_error;
@@ -9798,6 +9776,8 @@ ssl3_HandleCertificateVerify(sslSocket *ss, SSL3Opaque *b, PRUint32 length,
goto loser; /* malformed. */
}
+ isTLS = (PRBool)(ss->ssl3.prSpec->version > SSL_LIBRARY_VERSION_3_0);
+
/* XXX verify that the key & kea match */
rv = ssl3_VerifySignedHashes(ss, sigScheme, hashesForVerify, &signed_hash);
if (rv != SECSuccess) {
@@ -9910,7 +9890,7 @@ ssl3_GenerateRSAPMS(sslSocket *ss, ssl3CipherSpec *spec,
*/
static SECStatus
ssl3_HandleRSAClientKeyExchange(sslSocket *ss,
- SSL3Opaque *b,
+ PRUint8 *b,
PRUint32 length,
sslKeyPair *serverKeyPair)
{
@@ -9928,9 +9908,9 @@ ssl3_HandleRSAClientKeyExchange(sslSocket *ss,
enc_pms.len = length;
if (ss->ssl3.prSpec->version > SSL_LIBRARY_VERSION_3_0) { /* isTLS */
- PRInt32 kLen;
- kLen = ssl3_ConsumeHandshakeNumber(ss, 2, &enc_pms.data, &enc_pms.len);
- if (kLen < 0) {
+ PRUint32 kLen;
+ rv = ssl3_ConsumeHandshakeNumber(ss, &kLen, 2, &enc_pms.data, &enc_pms.len);
+ if (rv != SECSuccess) {
PORT_SetError(SSL_ERROR_CLIENT_KEY_EXCHANGE_FAILURE);
return SECFailure;
}
@@ -10037,7 +10017,7 @@ ssl3_HandleRSAClientKeyExchange(sslSocket *ss,
static SECStatus
ssl3_HandleDHClientKeyExchange(sslSocket *ss,
- SSL3Opaque *b,
+ PRUint8 *b,
PRUint32 length,
sslKeyPair *serverKeyPair)
{
@@ -10095,7 +10075,7 @@ ssl3_HandleDHClientKeyExchange(sslSocket *ss,
* Caller must hold Handshake and RecvBuf locks.
*/
static SECStatus
-ssl3_HandleClientKeyExchange(sslSocket *ss, SSL3Opaque *b, PRUint32 length)
+ssl3_HandleClientKeyExchange(sslSocket *ss, PRUint8 *b, PRUint32 length)
{
sslKeyPair *serverKeyPair = NULL;
SECStatus rv;
@@ -10227,7 +10207,7 @@ ssl3_SendNewSessionTicket(sslSocket *ss)
goto loser;
/* This is a fixed value. */
- rv = ssl3_AppendHandshakeNumber(ss, TLS_EX_SESS_TICKET_LIFETIME_HINT, 4);
+ rv = ssl3_AppendHandshakeNumber(ss, ssl_ticket_lifetime, 4);
if (rv != SECSuccess)
goto loser;
@@ -10246,10 +10226,11 @@ loser:
}
static SECStatus
-ssl3_HandleNewSessionTicket(sslSocket *ss, SSL3Opaque *b, PRUint32 length)
+ssl3_HandleNewSessionTicket(sslSocket *ss, PRUint8 *b, PRUint32 length)
{
SECStatus rv;
SECItem ticketData;
+ PRUint32 temp;
SSL_TRC(3, ("%d: SSL3[%d]: handle session_ticket handshake",
SSL_GETPID(), ss->fd));
@@ -10270,14 +10251,19 @@ ssl3_HandleNewSessionTicket(sslSocket *ss, SSL3Opaque *b, PRUint32 length)
* until it has verified the server's Finished message." See the comment in
* ssl3_FinishHandshake for more details.
*/
- ss->ssl3.hs.newSessionTicket.received_timestamp = ssl_Time();
+ ss->ssl3.hs.newSessionTicket.received_timestamp = PR_Now();
if (length < 4) {
(void)SSL3_SendAlert(ss, alert_fatal, decode_error);
PORT_SetError(SSL_ERROR_RX_MALFORMED_NEW_SESSION_TICKET);
return SECFailure;
}
- ss->ssl3.hs.newSessionTicket.ticket_lifetime_hint =
- (PRUint32)ssl3_ConsumeHandshakeNumber(ss, 4, &b, &length);
+
+ rv = ssl3_ConsumeHandshakeNumber(ss, &temp, 4, &b, &length);
+ if (rv != SECSuccess) {
+ PORT_SetError(SSL_ERROR_RX_MALFORMED_NEW_SESSION_TICKET);
+ return SECFailure;
+ }
+ ss->ssl3.hs.newSessionTicket.ticket_lifetime_hint = temp;
rv = ssl3_ConsumeHandshakeVariable(ss, &ticketData, 2, &b, &length);
if (rv != SECSuccess || length != 0) {
@@ -10551,7 +10537,7 @@ ssl3_CleanupPeerCerts(sslSocket *ss)
* Caller must hold Handshake and RecvBuf locks.
*/
static SECStatus
-ssl3_HandleCertificateStatus(sslSocket *ss, SSL3Opaque *b, PRUint32 length)
+ssl3_HandleCertificateStatus(sslSocket *ss, PRUint8 *b, PRUint32 length)
{
SECStatus rv;
@@ -10570,23 +10556,22 @@ ssl3_HandleCertificateStatus(sslSocket *ss, SSL3Opaque *b, PRUint32 length)
}
SECStatus
-ssl_ReadCertificateStatus(sslSocket *ss, SSL3Opaque *b, PRUint32 length)
+ssl_ReadCertificateStatus(sslSocket *ss, PRUint8 *b, PRUint32 length)
{
- PRInt32 status, len;
+ PRUint32 status, len;
+ SECStatus rv;
PORT_Assert(!ss->sec.isServer);
/* Consume the CertificateStatusType enum */
- status = ssl3_ConsumeHandshakeNumber(ss, 1, &b, &length);
- if (status != 1 /* ocsp */) {
- ssl3_DecodeError(ss); /* sets error code */
- return SECFailure;
+ rv = ssl3_ConsumeHandshakeNumber(ss, &status, 1, &b, &length);
+ if (rv != SECSuccess || status != 1 /* ocsp */) {
+ return ssl3_DecodeError(ss);
}
- len = ssl3_ConsumeHandshakeNumber(ss, 3, &b, &length);
- if (len != length) {
- ssl3_DecodeError(ss); /* sets error code */
- return SECFailure;
+ rv = ssl3_ConsumeHandshakeNumber(ss, &len, 3, &b, &length);
+ if (rv != SECSuccess || len != length) {
+ return ssl3_DecodeError(ss);
}
#define MAX_CERTSTATUS_LEN 0x1ffff /* 128k - 1 */
@@ -10619,7 +10604,7 @@ ssl_ReadCertificateStatus(sslSocket *ss, SSL3Opaque *b, PRUint32 length)
* Caller must hold Handshake and RecvBuf locks.
*/
static SECStatus
-ssl3_HandleCertificate(sslSocket *ss, SSL3Opaque *b, PRUint32 length)
+ssl3_HandleCertificate(sslSocket *ss, PRUint8 *b, PRUint32 length)
{
SSL_TRC(3, ("%d: SSL3[%d]: handle certificate handshake",
SSL_GETPID(), ss->fd));
@@ -10639,12 +10624,12 @@ ssl3_HandleCertificate(sslSocket *ss, SSL3Opaque *b, PRUint32 length)
/* Called from ssl3_HandleCertificate
*/
SECStatus
-ssl3_CompleteHandleCertificate(sslSocket *ss, SSL3Opaque *b, PRUint32 length)
+ssl3_CompleteHandleCertificate(sslSocket *ss, PRUint8 *b, PRUint32 length)
{
ssl3CertNode *c;
ssl3CertNode *lastCert = NULL;
- PRInt32 remaining = 0;
- PRInt32 size;
+ PRUint32 remaining = 0;
+ PRUint32 size;
SECStatus rv;
PRBool isServer = ss->sec.isServer;
PRBool isTLS;
@@ -10660,10 +10645,10 @@ ssl3_CompleteHandleCertificate(sslSocket *ss, SSL3Opaque *b, PRUint32 length)
** normal no_certificates message to maximize interoperability.
*/
if (length) {
- remaining = ssl3_ConsumeHandshakeNumber(ss, 3, &b, &length);
- if (remaining < 0)
+ rv = ssl3_ConsumeHandshakeNumber(ss, &remaining, 3, &b, &length);
+ if (rv != SECSuccess)
goto loser; /* fatal alert already sent by ConsumeHandshake. */
- if ((PRUint32)remaining > length)
+ if (remaining > length)
goto decode_loser;
}
@@ -10694,15 +10679,14 @@ ssl3_CompleteHandleCertificate(sslSocket *ss, SSL3Opaque *b, PRUint32 length)
}
/* First get the peer cert. */
- remaining -= 3;
- if (remaining < 0)
+ if (remaining < 3)
goto decode_loser;
- size = ssl3_ConsumeHandshakeNumber(ss, 3, &b, &length);
- if (size <= 0)
+ remaining -= 3;
+ rv = ssl3_ConsumeHandshakeNumber(ss, &size, 3, &b, &length);
+ if (rv != SECSuccess)
goto loser; /* fatal alert already sent by ConsumeHandshake. */
-
- if (remaining < size)
+ if (size == 0 || remaining < size)
goto decode_loser;
certItem.data = b;
@@ -10722,15 +10706,14 @@ ssl3_CompleteHandleCertificate(sslSocket *ss, SSL3Opaque *b, PRUint32 length)
/* Now get all of the CA certs. */
while (remaining > 0) {
- remaining -= 3;
- if (remaining < 0)
+ if (remaining < 3)
goto decode_loser;
- size = ssl3_ConsumeHandshakeNumber(ss, 3, &b, &length);
- if (size <= 0)
+ remaining -= 3;
+ rv = ssl3_ConsumeHandshakeNumber(ss, &size, 3, &b, &length);
+ if (rv != SECSuccess)
goto loser; /* fatal alert already sent by ConsumeHandshake. */
-
- if (remaining < size)
+ if (size == 0 || remaining < size)
goto decode_loser;
certItem.data = b;
@@ -10759,9 +10742,6 @@ ssl3_CompleteHandleCertificate(sslSocket *ss, SSL3Opaque *b, PRUint32 length)
lastCert = c;
}
- if (remaining != 0)
- goto decode_loser;
-
SECKEY_UpdateCertPQG(ss->sec.peerCert);
if (!isServer &&
@@ -11049,13 +11029,10 @@ ssl3_ComputeTLSFinished(sslSocket *ss, ssl3CipherSpec *spec,
PK11Context *prf_context;
unsigned int retLen;
+ PORT_Assert(spec->master_secret);
if (!spec->master_secret) {
- const char *label = isServer ? "server finished" : "client finished";
- unsigned int len = 15;
- HASH_HashType hashType = ssl3_GetTls12HashType(ss);
- return ssl3_TLSPRFWithMasterSecret(spec, label, len, hashes->u.raw,
- hashes->len, tlsFinished->verify_data,
- sizeof tlsFinished->verify_data, hashType);
+ PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
+ return SECFailure;
}
if (spec->version < SSL_LIBRARY_VERSION_TLS_1_2) {
@@ -11088,9 +11065,10 @@ ssl3_ComputeTLSFinished(sslSocket *ss, ssl3CipherSpec *spec,
* ss->ssl3.crSpec).
*/
SECStatus
-ssl3_TLSPRFWithMasterSecret(ssl3CipherSpec *spec, const char *label,
- unsigned int labelLen, const unsigned char *val, unsigned int valLen,
- unsigned char *out, unsigned int outLen, HASH_HashType tls12HashType)
+ssl3_TLSPRFWithMasterSecret(sslSocket *ss, ssl3CipherSpec *spec,
+ const char *label, unsigned int labelLen,
+ const unsigned char *val, unsigned int valLen,
+ unsigned char *out, unsigned int outLen)
{
SECStatus rv = SECSuccess;
@@ -11101,6 +11079,12 @@ ssl3_TLSPRFWithMasterSecret(ssl3CipherSpec *spec, const char *label,
unsigned int retLen;
if (spec->version >= SSL_LIBRARY_VERSION_TLS_1_2) {
+ /* Bug 1312976 non-SHA256 exporters are broken. */
+ if (ssl3_GetPrfHashMechanism(ss) != CKM_SHA256) {
+ PORT_Assert(0);
+ PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
+ return SECFailure;
+ }
mech = CKM_NSS_TLS_PRF_GENERAL_SHA256;
}
prf_context = PK11_CreateContextBySymKey(mech, CKA_SIGN,
@@ -11143,9 +11127,7 @@ ssl3_SendNextProto(sslSocket *ss)
padding_len = 32 - ((ss->xtnData.nextProto.len + 2) % 32);
- rv = ssl3_AppendHandshakeHeader(ss, next_proto, ss->xtnData.nextProto.len +
- 2 +
- padding_len);
+ rv = ssl3_AppendHandshakeHeader(ss, next_proto, ss->xtnData.nextProto.len + 2 + padding_len);
if (rv != SECSuccess) {
return rv; /* error code set by AppendHandshakeHeader */
}
@@ -11298,7 +11280,7 @@ fail:
*/
SECStatus
ssl3_CacheWrappedMasterSecret(sslSocket *ss, sslSessionID *sid,
- ssl3CipherSpec *spec, SSLAuthType authType)
+ ssl3CipherSpec *spec)
{
PK11SymKey *wrappingKey = NULL;
PK11SlotInfo *symKeySlot;
@@ -11352,8 +11334,7 @@ ssl3_CacheWrappedMasterSecret(sslSocket *ss, sslSessionID *sid,
mechanism = PK11_GetBestWrapMechanism(symKeySlot);
if (mechanism != CKM_INVALID_MECHANISM) {
wrappingKey =
- ssl3_GetWrappingKey(ss, symKeySlot, ss->sec.serverCert,
- mechanism, pwArg);
+ ssl3_GetWrappingKey(ss, symKeySlot, mechanism, pwArg);
if (wrappingKey) {
mechanism = PK11_GetMechanism(wrappingKey); /* can't fail. */
}
@@ -11382,7 +11363,7 @@ ssl3_CacheWrappedMasterSecret(sslSocket *ss, sslSessionID *sid,
* Caller must hold Handshake and RecvBuf locks.
*/
static SECStatus
-ssl3_HandleFinished(sslSocket *ss, SSL3Opaque *b, PRUint32 length,
+ssl3_HandleFinished(sslSocket *ss, PRUint8 *b, PRUint32 length,
const SSL3Hashes *hashes)
{
sslSessionID *sid = ss->sec.ci.sid;
@@ -11560,9 +11541,7 @@ ssl3_FillInCachedSID(sslSocket *ss, sslSessionID *sid)
sid->expirationTime = sid->creationTime + ssl3_sid_timeout;
sid->localCert = CERT_DupCertificate(ss->sec.localCert);
if (ss->sec.isServer) {
- memcpy(&sid->certType, &ss->sec.serverCert->certType, sizeof(sid->certType));
- } else {
- sid->certType.authType = ssl_auth_null;
+ sid->namedCurve = ss->sec.serverCert->namedCurve;
}
if (ss->xtnData.nextProtoState != SSL_NEXT_PROTO_NO_SUPPORT &&
@@ -11586,8 +11565,7 @@ ssl3_FillInCachedSID(sslSocket *ss, sslSessionID *sid)
rv = SECSuccess;
} else {
rv = ssl3_CacheWrappedMasterSecret(ss, ss->sec.ci.sid,
- ss->ssl3.crSpec,
- ss->ssl3.hs.kea_def->authKeyType);
+ ss->ssl3.crSpec);
sid->u.ssl3.keys.msIsWrapped = PR_TRUE;
}
ssl_ReleaseSpecReadLock(ss); /*************************************/
@@ -11646,7 +11624,7 @@ ssl3_FinishHandshake(sslSocket *ss)
* Caller must hold Handshake and RecvBuf locks.
*/
SECStatus
-ssl3_HandleHandshakeMessage(sslSocket *ss, SSL3Opaque *b, PRUint32 length,
+ssl3_HandleHandshakeMessage(sslSocket *ss, PRUint8 *b, PRUint32 length,
PRBool endOfRecord)
{
SECStatus rv = SECSuccess;
@@ -11732,10 +11710,7 @@ ssl3_HandleHandshakeMessage(sslSocket *ss, SSL3Opaque *b, PRUint32 length,
/* Start new handshake hashes when we start a new handshake. Unless this is
* TLS 1.3 and we sent a HelloRetryRequest. */
if (ss->ssl3.hs.msg_type == client_hello && !ss->ssl3.hs.helloRetry) {
- rv = ssl3_RestartHandshakeHashes(ss);
- if (rv != SECSuccess) {
- return rv;
- }
+ ssl3_RestartHandshakeHashes(ss);
}
/* We should not include hello_request and hello_verify_request messages
* in the handshake hashes */
@@ -11835,7 +11810,7 @@ ssl3_HandleHandshakeMessage(sslSocket *ss, SSL3Opaque *b, PRUint32 length,
}
static SECStatus
-ssl3_HandlePostHelloHandshakeMessage(sslSocket *ss, SSL3Opaque *b,
+ssl3_HandlePostHelloHandshakeMessage(sslSocket *ss, PRUint8 *b,
PRUint32 length, SSL3Hashes *hashesPtr)
{
SECStatus rv;
@@ -12203,7 +12178,7 @@ ssl_RemoveTLSCBCPadding(sslBuffer *plaintext, unsigned int macSize)
static void
ssl_CBCExtractMAC(sslBuffer *plaintext,
unsigned int originalLength,
- SSL3Opaque *out,
+ PRUint8 *out,
unsigned int macSize)
{
unsigned char rotatedMac[MAX_MAC_LENGTH];
@@ -12314,9 +12289,9 @@ ssl3_UnprotectRecord(sslSocket *ss, SSL3Ciphertext *cText, sslBuffer *plaintext,
unsigned int originalLen = 0;
unsigned char header[13];
unsigned int headerLen;
- SSL3Opaque hash[MAX_MAC_LENGTH];
- SSL3Opaque givenHashBuf[MAX_MAC_LENGTH];
- SSL3Opaque *givenHash;
+ PRUint8 hash[MAX_MAC_LENGTH];
+ PRUint8 givenHashBuf[MAX_MAC_LENGTH];
+ PRUint8 *givenHash;
unsigned int hashBytes = MAX_MAC_LENGTH + 1;
SECStatus rv;
@@ -12347,7 +12322,7 @@ ssl3_UnprotectRecord(sslSocket *ss, SSL3Ciphertext *cText, sslBuffer *plaintext,
* component." Instead, we decrypt the first cipher block and then
* discard it before decrypting the rest.
*/
- SSL3Opaque iv[MAX_IV_LENGTH];
+ PRUint8 iv[MAX_IV_LENGTH];
int decoded;
ivLen = cipher_def->iv_size;
@@ -12521,17 +12496,14 @@ ssl3_HandleRecord(sslSocket *ss, SSL3Ciphertext *cText, sslBuffer *databuf)
ssl3CipherSpec *crSpec;
SSL3ContentType rType;
sslBuffer *plaintext;
- sslBuffer temp_buf;
+ sslBuffer temp_buf = { NULL, 0, 0 };
SSL3AlertDescription alert = internal_error;
PORT_Assert(ss->opt.noLocks || ssl_HaveRecvBufLock(ss));
if (!ss->ssl3.initialized) {
ssl_GetSSL3HandshakeLock(ss);
- rv = ssl3_InitState(ss);
+ ssl3_InitState(ss);
ssl_ReleaseSSL3HandshakeLock(ss);
- if (rv != SECSuccess) {
- return rv; /* ssl3_InitState has set the error code. */
- }
}
/* check for Token Presence */
@@ -12578,25 +12550,11 @@ ssl3_HandleRecord(sslSocket *ss, SSL3Ciphertext *cText, sslBuffer *databuf)
/* If we will be decompressing the buffer we need to decrypt somewhere
* other than into databuf */
if (crSpec->decompressor) {
- temp_buf.buf = NULL;
- temp_buf.space = 0;
plaintext = &temp_buf;
} else {
plaintext = databuf;
}
-
plaintext->len = 0; /* filled in by Unprotect call below. */
- if (plaintext->space < MAX_FRAGMENT_LENGTH) {
- rv = sslBuffer_Grow(plaintext, MAX_FRAGMENT_LENGTH + 2048);
- if (rv != SECSuccess) {
- ssl_ReleaseSpecReadLock(ss); /*************************/
- SSL_DBG(("%d: SSL3[%d]: HandleRecord, tried to get %d bytes",
- SSL_GETPID(), ss->fd, MAX_FRAGMENT_LENGTH + 2048));
- /* sslBuffer_Grow has set a memory error code. */
- /* Perhaps we should send an alert. (but we have no memory!) */
- return SECFailure;
- }
- }
/* We're waiting for another ClientHello, which will appear unencrypted.
* Use the content type to tell whether this is should be discarded.
@@ -12611,6 +12569,18 @@ ssl3_HandleRecord(sslSocket *ss, SSL3Ciphertext *cText, sslBuffer *databuf)
return SECSuccess;
}
+ if (plaintext->space < MAX_FRAGMENT_LENGTH) {
+ rv = sslBuffer_Grow(plaintext, MAX_FRAGMENT_LENGTH + 2048);
+ if (rv != SECSuccess) {
+ ssl_ReleaseSpecReadLock(ss); /*************************/
+ SSL_DBG(("%d: SSL3[%d]: HandleRecord, tried to get %d bytes",
+ SSL_GETPID(), ss->fd, MAX_FRAGMENT_LENGTH + 2048));
+ /* sslBuffer_Grow has set a memory error code. */
+ /* Perhaps we should send an alert. (but we have no memory!) */
+ return SECFailure;
+ }
+ }
+
#ifdef UNSAFE_FUZZER_MODE
rv = Null_Cipher(NULL, plaintext->buf, (int *)&plaintext->len,
plaintext->space, cText->buf->buf, cText->buf->len);
@@ -12632,6 +12602,9 @@ ssl3_HandleRecord(sslSocket *ss, SSL3Ciphertext *cText, sslBuffer *databuf)
SSL_DBG(("%d: SSL3[%d]: decryption failed", SSL_GETPID(), ss->fd));
+ /* Clear the temp buffer used for decompression upon failure. */
+ sslBuffer_Clear(&temp_buf);
+
if (IS_DTLS(ss) ||
(ss->sec.isServer &&
ss->ssl3.hs.zeroRttIgnore == ssl_0rtt_ignore_trial)) {
@@ -12676,7 +12649,7 @@ ssl3_HandleRecord(sslSocket *ss, SSL3Ciphertext *cText, sslBuffer *databuf)
SSL3_COMPRESSION_MAX_EXPANSION));
/* sslBuffer_Grow has set a memory error code. */
/* Perhaps we should send an alert. (but we have no memory!) */
- PORT_Free(plaintext->buf);
+ sslBuffer_Clear(&temp_buf);
return SECFailure;
}
}
@@ -12714,12 +12687,12 @@ ssl3_HandleRecord(sslSocket *ss, SSL3Ciphertext *cText, sslBuffer *databuf)
}
}
- PORT_Free(plaintext->buf);
+ sslBuffer_Clear(&temp_buf);
PORT_SetError(err);
return SECFailure;
}
- PORT_Free(plaintext->buf);
+ sslBuffer_Clear(&temp_buf);
}
/*
@@ -12849,16 +12822,14 @@ ssl3_InitCipherSpec(ssl3CipherSpec *spec)
** ssl3_HandleRecord()
**
** This function should perhaps acquire and release the SpecWriteLock.
-**
-**
*/
-SECStatus
+void
ssl3_InitState(sslSocket *ss)
{
PORT_Assert(ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss));
if (ss->ssl3.initialized)
- return SECSuccess; /* Function should be idempotent */
+ return; /* Function should be idempotent */
ss->ssl3.policy = SSL_ALLOWED;
@@ -12913,7 +12884,6 @@ ssl3_InitState(sslSocket *ss)
ssl_FilterSupportedGroups(ss);
ss->ssl3.initialized = PR_TRUE;
- return SECSuccess;
}
/* record the export policy for this cipher suite */
@@ -13136,7 +13106,7 @@ SSL_SignaturePrefGet(PRFileDesc *fd, SSLSignatureAndHashAlg *algorithms,
}
unsigned int
-SSL_SignatureMaxCount()
+SSL_SignatureMaxCount(void)
{
return MAX_SIGNATURE_SCHEMES;
}