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

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

Issue 9558017: Update net/third_party/nss to NSS 3.13.3. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: Upload before checkin Created 8 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « net/third_party/nss/ssl/ssl3ecc.c ('k') | net/third_party/nss/ssl/ssl3gthr.c » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: net/third_party/nss/ssl/ssl3ext.c
===================================================================
--- net/third_party/nss/ssl/ssl3ext.c (revision 124804)
+++ net/third_party/nss/ssl/ssl3ext.c (working copy)
@@ -41,7 +41,7 @@
* ***** END LICENSE BLOCK ***** */
/* TLS extension code moved here from ssl3ecc.c */
-/* $Id: ssl3ext.c,v 1.14 2010/04/03 19:19:07 nelson%bolyard.com Exp $ */
+/* $Id: ssl3ext.c,v 1.21 2012/02/15 21:52:08 kaie%kuix.de Exp $ */
#include "nssrenam.h"
#include "nss.h"
@@ -56,7 +56,7 @@
static PK11SymKey *session_ticket_enc_key_pkcs11 = NULL;
static PK11SymKey *session_ticket_mac_key_pkcs11 = NULL;
-static unsigned char session_ticket_enc_key[32];
+static unsigned char session_ticket_enc_key[AES_256_KEY_LENGTH];
static unsigned char session_ticket_mac_key[SHA256_LENGTH];
static PRBool session_ticket_keys_initialized = PR_FALSE;
@@ -78,6 +78,12 @@
PRBool append, PRUint32 maxBytes);
static SECStatus ssl3_HandleRenegotiationInfoXtn(sslSocket *ss,
PRUint16 ex_type, SECItem *data);
+static SECStatus ssl3_ClientHandleNextProtoNegoXtn(sslSocket *ss,
+ PRUint16 ex_type, SECItem *data);
+static SECStatus ssl3_ServerHandleNextProtoNegoXtn(sslSocket *ss,
+ PRUint16 ex_type, SECItem *data);
+static PRInt32 ssl3_ClientSendNextProtoNegoXtn(sslSocket *ss, PRBool append,
+ PRUint32 maxBytes);
static SECStatus ssl3_ServerHandleEncryptedClientCertsXtn(sslSocket *ss,
PRUint16 ex_type, SECItem *data);
static SECStatus ssl3_ClientHandleEncryptedClientCertsXtn(sslSocket *ss,
@@ -242,8 +248,7 @@
{ ssl_session_ticket_xtn, &ssl3_ServerHandleSessionTicketXtn },
{ ssl_encrypted_client_certs, &ssl3_ServerHandleEncryptedClientCertsXtn },
{ ssl_renegotiation_info_xtn, &ssl3_HandleRenegotiationInfoXtn },
- { ssl_next_proto_neg_xtn, &ssl3_ServerHandleNextProtoNegoXtn },
- { ssl_cached_info_xtn, &ssl3_ServerHandleCachedInfoXtn },
+ { ssl_next_proto_nego_xtn, &ssl3_ServerHandleNextProtoNegoXtn },
{ ssl_ob_cert_xtn, &ssl3_ServerHandleOBCertXtn },
{ -1, NULL }
};
@@ -256,8 +261,7 @@
{ ssl_session_ticket_xtn, &ssl3_ClientHandleSessionTicketXtn },
{ ssl_encrypted_client_certs, &ssl3_ClientHandleEncryptedClientCertsXtn },
{ ssl_renegotiation_info_xtn, &ssl3_HandleRenegotiationInfoXtn },
- { ssl_next_proto_neg_xtn, &ssl3_ClientHandleNextProtoNegoXtn },
- { ssl_cached_info_xtn, &ssl3_ClientHandleCachedInfoXtn },
+ { ssl_next_proto_nego_xtn, &ssl3_ClientHandleNextProtoNegoXtn },
{ ssl_cert_status_xtn, &ssl3_ClientHandleStatusRequestXtn },
{ ssl_ob_cert_xtn, &ssl3_ClientHandleOBCertXtn },
{ -1, NULL }
@@ -284,8 +288,7 @@
#endif
{ ssl_session_ticket_xtn, &ssl3_SendSessionTicketXtn },
{ ssl_encrypted_client_certs, &ssl3_SendEncryptedClientCertsXtn },
- { ssl_next_proto_neg_xtn, &ssl3_ClientSendNextProtoNegoXtn },
- { ssl_cached_info_xtn, &ssl3_ClientSendCachedInfoXtn },
+ { ssl_next_proto_nego_xtn, &ssl3_ClientSendNextProtoNegoXtn },
{ ssl_cert_status_xtn, &ssl3_ClientSendStatusRequestXtn },
{ ssl_ob_cert_xtn, &ssl3_SendOBCertXtn }
/* any extra entries will appear as { 0, NULL } */
@@ -555,11 +558,12 @@
}
/* handle an incoming Next Protocol Negotiation extension. */
-SECStatus
+static SECStatus
ssl3_ServerHandleNextProtoNegoXtn(sslSocket * ss, PRUint16 ex_type, SECItem *data)
{
- if (data->len != 0) {
+ if (ss->firstHsDone || data->len != 0) {
/* Clients MUST send an empty NPN extension, if any. */
+ PORT_SetError(SSL_ERROR_NEXT_PROTOCOL_DATA_INVALID);
return SECFailure;
}
@@ -570,16 +574,20 @@
* of the lengths may be 0 and the sum of the lengths must equal the length of
* the block. */
SECStatus
-ssl3_ValidateNextProtoNego(const unsigned char* data, unsigned short length)
+ssl3_ValidateNextProtoNego(const unsigned char* data, unsigned int length)
{
unsigned int offset = 0;
while (offset < length) {
- if (data[offset] == 0) {
+ unsigned int newOffset = offset + 1 + (unsigned int) data[offset];
+ /* Reject embedded nulls to protect against buggy applications that
+ * store protocol identifiers in null-terminated strings.
+ */
+ if (newOffset > length || data[offset] == 0) {
PORT_SetError(SSL_ERROR_NEXT_PROTOCOL_DATA_INVALID);
return SECFailure;
}
- offset += (unsigned int)data[offset] + 1;
+ offset = newOffset;
}
if (offset > length) {
@@ -590,39 +598,51 @@
return SECSuccess;
}
-SECStatus
+static SECStatus
ssl3_ClientHandleNextProtoNegoXtn(sslSocket *ss, PRUint16 ex_type,
- SECItem *data)
+ SECItem *data)
{
SECStatus rv;
- unsigned char result[255];
- unsigned int result_len;
+ unsigned char resultBuffer[255];
+ SECItem result = { siBuffer, resultBuffer, 0 };
+ if (ss->firstHsDone) {
+ PORT_SetError(SSL_ERROR_NEXT_PROTOCOL_DATA_INVALID);
+ return SECFailure;
+ }
+
rv = ssl3_ValidateNextProtoNego(data->data, data->len);
if (rv != SECSuccess)
return rv;
- rv = ss->nextProtoCallback(ss->nextProtoArg, ss->fd,
- data->data, data->len,
- result, &result_len);
+ /* ss->nextProtoCallback cannot normally be NULL if we negotiated the
+ * extension. However, It is possible that an application erroneously
+ * cleared the callback between the time we sent the ClientHello and now.
+ */
+ PORT_Assert(ss->nextProtoCallback != NULL);
+ if (!ss->nextProtoCallback) {
+ PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
+ return SECFailure;
+ }
+
+ rv = ss->nextProtoCallback(ss->nextProtoArg, ss->fd, data->data, data->len,
+ result.data, &result.len, sizeof resultBuffer);
if (rv != SECSuccess)
return rv;
/* If the callback wrote more than allowed to |result| it has corrupted our
* stack. */
- PORT_Assert(result_len <= sizeof(result));
+ if (result.len > sizeof result) {
+ PORT_SetError(SEC_ERROR_OUTPUT_LEN);
+ return SECFailure;
+ }
- if (ss->ssl3.nextProto.data)
- PORT_Free(ss->ssl3.nextProto.data);
- ss->ssl3.nextProto.data = PORT_Alloc(result_len);
- PORT_Memcpy(ss->ssl3.nextProto.data, result, result_len);
- ss->ssl3.nextProto.len = result_len;
- return SECSuccess;
+ SECITEM_FreeItem(&ss->ssl3.nextProto, PR_FALSE);
+ return SECITEM_CopyItem(NULL, &ss->ssl3.nextProto, &result);
}
-PRInt32
-ssl3_ClientSendNextProtoNegoXtn(sslSocket * ss,
- PRBool append,
- PRUint32 maxBytes)
+static PRInt32
+ssl3_ClientSendNextProtoNegoXtn(sslSocket * ss, PRBool append,
+ PRUint32 maxBytes)
{
PRInt32 extension_length;
@@ -635,21 +655,21 @@
if (append && maxBytes >= extension_length) {
SECStatus rv;
- rv = ssl3_AppendHandshakeNumber(ss, ssl_next_proto_neg_xtn, 2);
+ rv = ssl3_AppendHandshakeNumber(ss, ssl_next_proto_nego_xtn, 2);
if (rv != SECSuccess)
goto loser;
rv = ssl3_AppendHandshakeNumber(ss, 0, 2);
if (rv != SECSuccess)
goto loser;
ss->xtnData.advertised[ss->xtnData.numAdvertised++] =
- ssl_next_proto_neg_xtn;
+ ssl_next_proto_nego_xtn;
} else if (maxBytes < extension_length) {
return 0;
}
return extension_length;
- loser:
+loser:
return -1;
}
@@ -673,261 +693,6 @@
return SECSuccess;
}
-/* ssl3_ClientSendCachedInfoXtn builds the cached_info extension on the
- * client side. */
-PRInt32
-ssl3_ClientSendCachedInfoXtn(sslSocket * ss, PRBool append,
- PRUint32 maxBytes)
-{
- PRInt32 extension_length;
- PRBool send_empty;
- CERTCertificate ** predictedCertChain;
-
- if (!ss->opt.enableCachedInfo)
- return 0;
-
- predictedCertChain = ss->ssl3.predictedCertChain;
- send_empty = (predictedCertChain == NULL);
-
- /* minimum extension:
- * extension_type (2-bytes) +
- * length(extension_data) (2-bytes) +
- * length(cached_info) (2-bytes) +
- */
- extension_length = send_empty ? 6 : 16;
-
- if (append && maxBytes >= extension_length) {
- SECStatus rv;
-
- /* ExtensionType */
- rv = ssl3_AppendHandshakeNumber(ss, ssl_cached_info_xtn, 2);
- if (rv != SECSuccess)
- return -1;
- /* Extension Length */
- rv = ssl3_AppendHandshakeNumber(ss, extension_length - 4, 2);
- if (rv != SECSuccess)
- return -1;
- if (send_empty) {
- /* Cached Information Length */
- rv = ssl3_AppendHandshakeNumber(ss, 0, 2);
- if (rv != SECSuccess)
- return -1;
- } else {
- PRUint64 certChainHash;
- int i;
- PRUint8* digestPtr = (PRUint8*) &certChainHash;
-
- /* Cached Information Length */
- rv = ssl3_AppendHandshakeNumber(ss, 10, 2);
- if (rv != SECSuccess)
- return -1;
- /* Cached Information Type */
- rv = ssl3_AppendHandshakeNumber(ss, 1 /* certificate_chain */, 1);
- if (rv != SECSuccess)
- return -1;
- /* hash length */
- rv = ssl3_AppendHandshakeNumber(ss, 8, 1);
- if (rv != SECSuccess)
- return -1;
- /* hash */
- FNV1A64_Init(&certChainHash);
- for (i = 0; predictedCertChain[i] != NULL; i++) {
- unsigned int certLen = predictedCertChain[i]->derCert.len;
- unsigned char certLenArray[3] = {
- certLen >> 16,
- certLen >> 8,
- certLen
- };
- FNV1A64_Update(&certChainHash, certLenArray, 3);
- FNV1A64_Update(&certChainHash,
- predictedCertChain[i]->derCert.data, certLen);
- }
- FNV1A64_Final(&certChainHash);
- rv = ssl3_AppendHandshake(ss, &certChainHash, 8);
- if (rv != SECSuccess)
- return -1;
- for (i = 0; i < 8; i++) {
- ss->ssl3.certChainDigest[i] = digestPtr[i];
- }
- }
-
- } else if (maxBytes < extension_length) {
- PORT_Assert(0);
- return 0;
- }
- ss->xtnData.advertised[ss->xtnData.numAdvertised++] =
- ssl_cached_info_xtn;
- return extension_length;
-}
-
-SECStatus
-ssl3_ServerHandleCachedInfoXtn(sslSocket *ss, PRUint16 ex_type,
- SECItem *data)
-{
- SECStatus rv;
- unsigned char *cached_info = data->data;
- unsigned int remaining_len;
-
- /* Ignore the extension if it isn't enabled. */
- if (!ss->opt.enableCachedInfo)
- return SECSuccess;
-
- if (data->len < 2)
- return SECFailure;
- remaining_len = (cached_info[0] << 8) | cached_info[1];
- if (remaining_len > 2048 || remaining_len != data->len - 2)
- return SECFailure;
- cached_info += 2;
-
- /* Handle reconnaissance case. */
- if (remaining_len == 0) {
- /* The client supports information caching, but provides no information
- * about what information types it supports */
- ss->xtnData.negotiated[ss->xtnData.numNegotiated++] = ex_type;
- rv = ssl3_RegisterServerHelloExtensionSender(ss, ex_type,
- ssl3_ServerSendCachedInfoXtn);
- return rv;
- }
-
- /* Iterate over the CachedObjects and pick the first item of type
- * certificate_chain, while ignoring everything else. */
- while (remaining_len >= 2) {
- unsigned char cached_object_type = *cached_info++;
- unsigned int cached_object_length = *cached_info++;
- remaining_len -= 2;
- if (remaining_len < cached_object_length)
- return SECFailure;
- if (cached_object_length != 8) /* The digest must be present. */
- return SECFailure;
- if (cached_object_type == cached_info_certificate_chain &&
- !ss->ssl3.cachedInfoCertChainDigestReceived) {
- ss->ssl3.cachedInfoCertChainDigestReceived = PR_TRUE;
- memcpy(ss->ssl3.certChainDigest, cached_info, 8);
- }
- remaining_len -= cached_object_length;
- cached_info += cached_object_length;
- }
-
- if (remaining_len != 0)
- return SECFailure;
-
- if (ss->ssl3.cachedInfoCertChainDigestReceived) {
- ss->xtnData.negotiated[ss->xtnData.numNegotiated++] = ex_type;
- rv = ssl3_RegisterServerHelloExtensionSender(ss, ex_type,
- ssl3_ServerSendCachedInfoXtn);
- return SECSuccess;
- }
-
- return SECSuccess;
-}
-
-/* ssl3_ServerSendCachedInfoXtn builds the cached_info extension on the
- * server side. */
-PRInt32
-ssl3_ServerSendCachedInfoXtn(sslSocket * ss, PRBool append,
- PRUint32 maxBytes)
-{
- PRInt32 extension_length = 2 /* extension type */ +
- 2 /* extension length */ +
- 2 /* cached_info length */ +
- 1 /* CachedInformationType */ +
- 1 /* hash value length (0) */;
- SECStatus rv;
-
- PORT_Assert(ss->opt.enableCachedInfo);
-
- if (append && maxBytes >= extension_length) {
- /* ExtensionType */
- rv = ssl3_AppendHandshakeNumber(ss, ssl_cached_info_xtn, 2);
- if (rv != SECSuccess)
- return -1;
- /* Extension Length */
- rv = ssl3_AppendHandshakeNumber(ss, extension_length - 4, 2);
- if (rv != SECSuccess)
- return -1;
- /* Cached Information Length */
- rv = ssl3_AppendHandshakeNumber(ss, 2, 2);
- if (rv != SECSuccess)
- return -1;
- /* Cached Information Type */
- rv = ssl3_AppendHandshakeNumber(ss, 1 /* certificate_chain */, 1);
- if (rv != SECSuccess)
- return -1;
- /* hash length */
- rv = ssl3_AppendHandshakeNumber(ss, 0, 1);
- if (rv != SECSuccess)
- return -1;
- } else if (maxBytes < extension_length) {
- PORT_Assert(0);
- return 0;
- }
-
- return extension_length;
-}
-
-SECStatus
-ssl3_ClientHandleCachedInfoXtn(sslSocket *ss, PRUint16 ex_type,
- SECItem *data)
-{
- unsigned char * cached_info = data->data;
- unsigned int remaining_cached_info_length;
- PRBool has_correct_cert_chain = PR_FALSE;
-
- /* If we didn't request this extension, then the server may not echo it. */
- if (!ss->opt.enableCachedInfo)
- return SECFailure;
-
- if (data->len == 0) {
- /* The server supports information caching, but provides no information
- * about what information types it supports */
- ss->xtnData.negotiated[ss->xtnData.numNegotiated++] = ex_type;
- return SECSuccess;
- }
-
- if (data->len < 2)
- return SECFailure;
- remaining_cached_info_length = (cached_info[0] << 8) | cached_info[1];
- if (remaining_cached_info_length != data->len - 2)
- return SECFailure;
- cached_info += 2;
- while (remaining_cached_info_length >= 2) {
- /* The server supports only those CachedInformationType types that are
- * identified by a present CachedObject */
- unsigned char cached_object_type;
- unsigned int cached_object_length;
- unsigned char cached_object_digest[8];
- cached_object_type = *cached_info++;
- cached_object_length = *cached_info++;
- remaining_cached_info_length -= 2;
- if (remaining_cached_info_length < cached_object_length)
- return SECFailure;
- if (cached_object_length != 0 && cached_object_length != 8)
- return SECFailure;
- remaining_cached_info_length -= cached_object_length;
- if (cached_object_type == cached_info_certificate_chain) {
- if (cached_object_length == 0)
- has_correct_cert_chain = PR_TRUE;
- else { /* Hashes must match */
- int i;
- for (i = 0; i < 8; i++)
- cached_object_digest[i] = *cached_info++;
- if (!memcmp(cached_object_digest, ss->ssl3.certChainDigest, 8))
- has_correct_cert_chain = PR_TRUE;
- }
- }
- }
-
- if (remaining_cached_info_length != 0)
- return SECFailure;
-
- if (has_correct_cert_chain) {
- ss->xtnData.negotiated[ss->xtnData.numNegotiated++] = ex_type;
- return SECSuccess;
- }
-
- return SECFailure;
-}
-
/* ssl3_ClientSendStatusRequestXtn builds the status_request extension on the
* client side. See RFC 4366 section 3.6. */
PRInt32
@@ -1726,14 +1491,17 @@
SSL_GETPID(), ss->fd));
ssl3stats = SSL_GetStatistics();
SSL_AtomicIncrementLong(& ssl3stats->hch_sid_ticket_parse_failures );
- if (sid) {
- ssl_FreeSID(sid);
- sid = NULL;
- }
}
rv = SECSuccess;
loser:
+ /* ss->sec.ci.sid == sid if it did NOT come here via goto statement
+ * in that case do not free sid
+ */
+ if (sid && (ss->sec.ci.sid != sid)) {
+ ssl_FreeSID(sid);
+ sid = NULL;
+ }
if (decrypted_state != NULL) {
SECITEM_FreeItem(decrypted_state, PR_TRUE);
decrypted_state = NULL;
« no previous file with comments | « net/third_party/nss/ssl/ssl3ecc.c ('k') | net/third_party/nss/ssl/ssl3gthr.c » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698