Replace NSS with Pale Moon's

This commit is contained in:
wuggy 2026-06-29 21:29:25 +01:00
commit 8c2e376f94
2870 changed files with 1762232 additions and 1374220 deletions

View file

@ -15,7 +15,7 @@
#include "selfencrypt.h"
#include "ssl3ext.h"
#include "ssl3exthandle.h"
#include "tls13esni.h"
#include "tls13ech.h"
#include "tls13exthandle.h" /* For tls13_ServerSendStatusRequestXtn. */
PRBool
@ -42,13 +42,11 @@ ssl_ShouldSendSNIExtension(const sslSocket *ss, const char *url)
*/
SECStatus
ssl3_ClientFormatServerNameXtn(const sslSocket *ss, const char *url,
TLSExtensionData *xtnData,
unsigned int len, TLSExtensionData *xtnData,
sslBuffer *buf)
{
unsigned int len;
SECStatus rv;
len = PORT_Strlen(url);
/* length of server_name_list */
rv = sslBuffer_AppendNumber(buf, len + 3, 2);
if (rv != SECSuccess) {
@ -76,17 +74,15 @@ ssl3_ClientSendServerNameXtn(const sslSocket *ss, TLSExtensionData *xtnData,
const char *url = ss->url;
/* We only make an ESNI private key if we are going to
* send ESNI. */
if (ss->xtnData.esniPrivateKey != NULL) {
url = ss->esniKeys->dummySni;
}
if (!ssl_ShouldSendSNIExtension(ss, url)) {
return SECSuccess;
}
rv = ssl3_ClientFormatServerNameXtn(ss, url, xtnData, buf);
/* If ECH, write the public name. The real server name
* is emplaced while constructing CHInner extensions. */
sslEchConfig *cfg = (sslEchConfig *)PR_LIST_HEAD(&ss->echConfigs);
const char *sniContents = PR_CLIST_IS_EMPTY(&ss->echConfigs) ? url : cfg->contents.publicName;
rv = ssl3_ClientFormatServerNameXtn(ss, sniContents, strlen(sniContents), xtnData, buf);
if (rv != SECSuccess) {
return SECFailure;
}
@ -107,13 +103,6 @@ ssl3_HandleServerNameXtn(const sslSocket *ss, TLSExtensionData *xtnData,
return SECSuccess; /* ignore extension */
}
if (ssl3_ExtensionNegotiated(ss, ssl_tls13_encrypted_sni_xtn)) {
/* If we already have ESNI, make sure we don't overwrite
* the value. */
PORT_Assert(ss->version >= SSL_LIBRARY_VERSION_TLS_1_3);
return SECSuccess;
}
/* Server side - consume client data and register server sender. */
/* do not parse the data if don't have user extension handling function. */
if (!ss->sniSocketConfig) {
@ -176,7 +165,7 @@ ssl3_HandleServerNameXtn(const sslSocket *ss, TLSExtensionData *xtnData,
ssl3_FreeSniNameArray(xtnData);
xtnData->sniNameArr = names;
xtnData->sniNameArrSize = 1;
xtnData->negotiated[xtnData->numNegotiated++] = ssl_server_name_xtn;
ssl3_RecordExtensionNegotiated(ss, xtnData, ssl_server_name_xtn);
}
return SECSuccess;
@ -212,7 +201,7 @@ ssl3_FreeSniNameArray(TLSExtensionData *xtnData)
* Clients sends a filled in session ticket if one is available, and otherwise
* sends an empty ticket. Servers always send empty tickets.
*/
PRInt32
SECStatus
ssl3_ClientSendSessionTicketXtn(const sslSocket *ss, TLSExtensionData *xtnData,
sslBuffer *buf, PRBool *added)
{
@ -319,15 +308,15 @@ ssl3_SelectAppProtocol(const sslSocket *ss, TLSExtensionData *xtnData,
if (rv != SECSuccess) {
ssl3_ExtSendAlert(ss, alert_fatal, decode_error);
PORT_SetError(SSL_ERROR_NEXT_PROTOCOL_DATA_INVALID);
return rv;
return SECFailure;
}
PORT_Assert(ss->nextProtoCallback);
/* The cipher suite isn't selected yet. Note that extensions
/* Neither the cipher suite nor ECH are selected yet Note that extensions
* sometimes affect what cipher suite is selected, e.g., for ECC. */
PORT_Assert((ss->ssl3.hs.preliminaryInfo &
ssl_preinfo_all & ~ssl_preinfo_cipher_suite) ==
(ssl_preinfo_all & ~ssl_preinfo_cipher_suite));
ssl_preinfo_all & ~ssl_preinfo_cipher_suite & ~ssl_preinfo_ech) ==
(ssl_preinfo_all & ~ssl_preinfo_cipher_suite & ~ssl_preinfo_ech));
/* The callback has to make sure that either rv != SECSuccess or that result
* is not set if there is no common protocol. */
rv = ss->nextProtoCallback(ss->nextProtoArg, ss->fd, data->data, data->len,
@ -356,7 +345,7 @@ ssl3_SelectAppProtocol(const sslSocket *ss, TLSExtensionData *xtnData,
}
xtnData->nextProtoState = SSL_NEXT_PROTO_NEGOTIATED;
xtnData->negotiated[xtnData->numNegotiated++] = extension;
ssl3_RecordExtensionNegotiated(ss, xtnData, extension);
return SECITEM_CopyItem(NULL, &xtnData->nextProto, &result);
}
@ -458,7 +447,7 @@ ssl3_ClientHandleAppProtoXtn(const sslSocket *ss, TLSExtensionData *xtnData,
SECITEM_FreeItem(&xtnData->nextProto, PR_FALSE);
xtnData->nextProtoState = SSL_NEXT_PROTO_SELECTED;
xtnData->negotiated[xtnData->numNegotiated++] = ssl_app_layer_protocol_xtn;
ssl3_RecordExtensionNegotiated(ss, xtnData, ssl_app_layer_protocol_xtn);
return SECITEM_CopyItem(NULL, &xtnData->nextProto, &protocol_name);
}
@ -467,20 +456,33 @@ ssl3_ClientSendAppProtoXtn(const sslSocket *ss, TLSExtensionData *xtnData,
sslBuffer *buf, PRBool *added)
{
SECStatus rv;
const unsigned int len = ss->opt.nextProtoNego.len;
/* Renegotiations do not send this extension. */
if (!ss->opt.enableALPN || !ss->opt.nextProtoNego.data || ss->firstHsDone) {
if (!ss->opt.enableALPN || !ss->opt.nextProtoNego.len || ss->firstHsDone) {
PR_ASSERT(!ss->opt.nextProtoNego.data);
return SECSuccess;
}
PRBool addGrease = ss->opt.enableGrease && ss->vrange.max >= SSL_LIBRARY_VERSION_TLS_1_3;
if (len > 0) {
/* Each protocol string is prefixed with a single byte length. */
rv = sslBuffer_AppendNumber(buf, len, 2);
/* The list of protocol strings is prefixed with a 2-byte length */
rv = sslBuffer_AppendNumber(buf, ss->opt.nextProtoNego.len + (addGrease ? 3 : 0), 2);
if (rv != SECSuccess) {
return SECFailure;
}
/* The list of protocol strings */
rv = sslBuffer_Append(buf, ss->opt.nextProtoNego.data, ss->opt.nextProtoNego.len);
if (rv != SECSuccess) {
return SECFailure;
}
/* A client MAY select one or more GREASE ALPN identifiers and advertise
* them in the "application_layer_protocol_negotiation" extension, if sent
* [RFC8701, Section 3.1]. */
if (addGrease) {
rv = sslBuffer_AppendNumber(buf, 2, 1);
if (rv != SECSuccess) {
return SECFailure;
}
rv = sslBuffer_Append(buf, ss->opt.nextProtoNego.data, len);
rv = sslBuffer_AppendNumber(buf, ss->ssl3.hs.grease->idx[grease_alpn], 2);
if (rv != SECSuccess) {
return SECFailure;
}
@ -526,7 +528,7 @@ ssl3_ServerHandleStatusRequestXtn(const sslSocket *ss, TLSExtensionData *xtnData
PORT_Assert(ss->sec.isServer);
/* remember that we got this extension. */
xtnData->negotiated[xtnData->numNegotiated++] = ssl_cert_status_xtn;
ssl3_RecordExtensionNegotiated(ss, xtnData, ssl_cert_status_xtn);
if (ss->version >= SSL_LIBRARY_VERSION_TLS_1_3) {
sender = tls13_ServerSendStatusRequestXtn;
@ -604,7 +606,7 @@ ssl3_ClientHandleStatusRequestXtn(const sslSocket *ss, TLSExtensionData *xtnData
}
/* Keep track of negotiated extensions. */
xtnData->negotiated[xtnData->numNegotiated++] = ssl_cert_status_xtn;
ssl3_RecordExtensionNegotiated(ss, xtnData, ssl_cert_status_xtn);
return SECSuccess;
}
@ -796,7 +798,7 @@ ssl3_EncodeSessionTicket(sslSocket *ss, const NewSessionTicket *ticket,
* This is compared to the expected time, which should differ only as a
* result of clock errors or errors in the RTT estimate.
*/
ticketAgeBaseline = (ssl_Time(ss) - ss->ssl3.hs.serverHelloTime) / PR_USEC_PER_MSEC;
ticketAgeBaseline = ss->ssl3.hs.rttEstimate / PR_USEC_PER_MSEC;
ticketAgeBaseline -= ticket->ticket_age_add;
rv = sslBuffer_AppendNumber(&plaintext, ticketAgeBaseline, 4);
if (rv != SECSuccess)
@ -857,7 +859,7 @@ ssl3_ClientHandleSessionTicketXtn(const sslSocket *ss, TLSExtensionData *xtnData
}
/* Keep track of negotiated extensions. */
xtnData->negotiated[xtnData->numNegotiated++] = ssl_session_ticket_xtn;
ssl3_RecordExtensionNegotiated(ss, xtnData, ssl_session_ticket_xtn);
return SECSuccess;
}
@ -928,6 +930,13 @@ ssl_ParseSessionTicket(sslSocket *ss, const SECItem *decryptedTicket,
PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
return SECFailure;
}
#ifndef UNSAFE_FUZZER_MODE
PORT_Assert(temp < ssl_auth_size);
#else
temp %= (8 * sizeof(SSLAuthType)) - 1;
#endif
parsedTicket->authType = (SSLAuthType)temp;
rv = ssl3_ExtConsumeHandshakeNumber(ss, &temp, 4, &buffer, &len);
if (rv != SECSuccess) {
@ -1034,7 +1043,9 @@ ssl_ParseSessionTicket(sslSocket *ss, const SECItem *decryptedTicket,
PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
return SECFailure;
}
parsedTicket->timestamp = (PRTime)temp << 32;
/* Cast to avoid undefined behavior if the top bit is set. */
parsedTicket->timestamp = (PRTime)((PRUint64)temp << 32);
rv = ssl3_ExtConsumeHandshakeNumber(ss, &temp, 4, &buffer, &len);
if (rv != SECSuccess) {
PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
@ -1056,8 +1067,11 @@ ssl_ParseSessionTicket(sslSocket *ss, const SECItem *decryptedTicket,
PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
return SECFailure;
}
#ifndef UNSAFE_FUZZER_MODE
/* A well-behaving server should only write 0 or 1. */
PORT_Assert(temp == PR_TRUE || temp == PR_FALSE);
parsedTicket->extendedMasterSecretUsed = (PRBool)temp;
#endif
parsedTicket->extendedMasterSecretUsed = temp ? PR_TRUE : PR_FALSE;
rv = ssl3_ExtConsumeHandshake(ss, &temp, 4, &buffer, &len);
if (rv != SECSuccess) {
@ -1295,7 +1309,7 @@ ssl3_ServerHandleSessionTicketXtn(const sslSocket *ss, TLSExtensionData *xtnData
}
/* Keep track of negotiated extensions. */
xtnData->negotiated[xtnData->numNegotiated++] = ssl_session_ticket_xtn;
ssl3_RecordExtensionNegotiated(ss, xtnData, ssl_session_ticket_xtn);
/* Parse the received ticket sent in by the client. We are
* lenient about some parse errors, falling back to a fullshake
@ -1373,7 +1387,7 @@ ssl3_HandleRenegotiationInfoXtn(const sslSocket *ss, TLSExtensionData *xtnData,
/* remember that we got this extension and it was correct. */
CONST_CAST(sslSocket, ss)
->peerRequestedProtection = 1;
xtnData->negotiated[xtnData->numNegotiated++] = ssl_renegotiation_info_xtn;
ssl3_RecordExtensionNegotiated(ss, xtnData, ssl_renegotiation_info_xtn);
if (ss->sec.isServer) {
/* prepare to send back the appropriate response */
rv = ssl3_RegisterExtensionSender(ss, xtnData,
@ -1508,7 +1522,7 @@ ssl3_ClientHandleUseSRTPXtn(const sslSocket *ss, TLSExtensionData *xtnData,
}
/* OK, this looks fine. */
xtnData->negotiated[xtnData->numNegotiated++] = ssl_use_srtp_xtn;
ssl3_RecordExtensionNegotiated(ss, xtnData, ssl_use_srtp_xtn);
xtnData->dtlsSRTPCipherSuite = cipher;
return SECSuccess;
}
@ -1579,7 +1593,7 @@ ssl3_ServerHandleUseSRTPXtn(const sslSocket *ss, TLSExtensionData *xtnData,
/* OK, we have a valid cipher and we've selected it */
xtnData->dtlsSRTPCipherSuite = cipher;
xtnData->negotiated[xtnData->numNegotiated++] = ssl_use_srtp_xtn;
ssl3_RecordExtensionNegotiated(ss, xtnData, ssl_use_srtp_xtn);
return ssl3_RegisterExtensionSender(ss, xtnData,
ssl_use_srtp_xtn,
@ -1625,8 +1639,12 @@ ssl3_HandleSigAlgsXtn(const sslSocket *ss, TLSExtensionData *xtnData,
return SECFailure;
}
/* Keep track of negotiated extensions. */
xtnData->negotiated[xtnData->numNegotiated++] = ssl_signature_algorithms_xtn;
/* Keep track of negotiated extensions. Only the server consumes this
* entry; on the client, skipping prevents numNegotiated overflow
* during repeated post-handshake CertificateRequests. */
if (ss->sec.isServer) {
ssl3_RecordExtensionNegotiated(ss, xtnData, ssl_signature_algorithms_xtn);
}
return SECSuccess;
}
@ -1647,7 +1665,8 @@ ssl3_SendSigAlgsXtn(const sslSocket *ss, TLSExtensionData *xtnData,
minVersion = ss->vrange.min; /* ClientHello */
}
SECStatus rv = ssl3_EncodeSigAlgs(ss, minVersion, buf);
SECStatus rv = ssl3_EncodeSigAlgs(ss, minVersion, PR_TRUE /* forCert */,
ss->opt.enableGrease, buf);
if (rv != SECSuccess) {
return SECFailure;
}
@ -1696,7 +1715,7 @@ ssl3_HandleExtendedMasterSecretXtn(const sslSocket *ss, TLSExtensionData *xtnDat
SSL_GETPID(), ss->fd));
/* Keep track of negotiated extensions. */
xtnData->negotiated[xtnData->numNegotiated++] = ssl_extended_master_secret_xtn;
ssl3_RecordExtensionNegotiated(ss, xtnData, ssl_extended_master_secret_xtn);
if (ss->sec.isServer) {
return ssl3_RegisterExtensionSender(ss, xtnData,
@ -1743,7 +1762,7 @@ ssl3_ClientHandleSignedCertTimestampXtn(const sslSocket *ss, TLSExtensionData *x
}
*scts = *data;
/* Keep track of negotiated extensions. */
xtnData->negotiated[xtnData->numNegotiated++] = ssl_signed_cert_timestamp_xtn;
ssl3_RecordExtensionNegotiated(ss, xtnData, ssl_signed_cert_timestamp_xtn);
return SECSuccess;
}
@ -1779,7 +1798,7 @@ ssl3_ServerHandleSignedCertTimestampXtn(const sslSocket *ss,
return SECFailure;
}
xtnData->negotiated[xtnData->numNegotiated++] = ssl_signed_cert_timestamp_xtn;
ssl3_RecordExtensionNegotiated(ss, xtnData, ssl_signed_cert_timestamp_xtn);
PORT_Assert(ss->sec.isServer);
return ssl3_RegisterExtensionSender(ss, xtnData,
ssl_signed_cert_timestamp_xtn,
@ -1812,8 +1831,16 @@ ssl3_HandleSupportedPointFormatsXtn(const sslSocket *ss,
}
}
/* Poor client doesn't support uncompressed points. */
/* Poor client doesn't support uncompressed points.
*
* If the client sends the extension and the extension does not contain the
* uncompressed point format, and the client has used the Supported Groups
* extension to indicate support for any of the curves defined in this
* specification, then the server MUST abort the handshake and return an
* illegal_parameter alert. [RFC8422, Section 5.1.2] */
ssl3_ExtSendAlert(ss, alert_fatal, illegal_parameter);
PORT_SetError(SSL_ERROR_RX_MALFORMED_HANDSHAKE);
return SECFailure;
}
@ -1911,7 +1938,7 @@ ssl_HandleSupportedGroupsXtn(const sslSocket *ss, TLSExtensionData *xtnData,
}
/* Remember that we negotiated this extension. */
xtnData->negotiated[xtnData->numNegotiated++] = ssl_supported_groups_xtn;
ssl3_RecordExtensionNegotiated(ss, xtnData, ssl_supported_groups_xtn);
return SECSuccess;
}
@ -1952,7 +1979,7 @@ ssl_HandleRecordSizeLimitXtn(const sslSocket *ss, TLSExtensionData *xtnData,
/* We can't enforce the maximum on a server. But we do need to ensure
* that we don't apply a limit that is too large. */
xtnData->recordSizeLimit = PR_MIN(maxLimit, limit);
xtnData->negotiated[xtnData->numNegotiated++] = ssl_record_size_limit_xtn;
ssl3_RecordExtensionNegotiated(ss, xtnData, ssl_record_size_limit_xtn);
return SECSuccess;
}