summaryrefslogtreecommitdiffstats
path: root/security/nss/lib/ssl/sslsecur.c
diff options
context:
space:
mode:
Diffstat (limited to 'security/nss/lib/ssl/sslsecur.c')
-rw-r--r--security/nss/lib/ssl/sslsecur.c77
1 files changed, 58 insertions, 19 deletions
diff --git a/security/nss/lib/ssl/sslsecur.c b/security/nss/lib/ssl/sslsecur.c
index eecf44396..8bec3d327 100644
--- a/security/nss/lib/ssl/sslsecur.c
+++ b/security/nss/lib/ssl/sslsecur.c
@@ -478,7 +478,7 @@ sslBuffer_Append(sslBuffer *b, const void *data, unsigned int len)
void
sslBuffer_Clear(sslBuffer *b)
{
- if (b->len > 0) {
+ if (b->buf) {
PORT_Free(b->buf);
b->buf = NULL;
b->len = 0;
@@ -884,6 +884,7 @@ int
ssl_SecureSend(sslSocket *ss, const unsigned char *buf, int len, int flags)
{
int rv = 0;
+ PRBool zeroRtt = PR_FALSE;
SSL_TRC(2, ("%d: SSL[%d]: SecureSend: sending %d bytes",
SSL_GETPID(), ss->fd, len));
@@ -923,19 +924,20 @@ ssl_SecureSend(sslSocket *ss, const unsigned char *buf, int len, int flags)
* Case 2: TLS 1.3 0-RTT
*/
if (!ss->firstHsDone) {
- PRBool falseStart = PR_FALSE;
+ PRBool allowEarlySend = PR_FALSE;
+
ssl_Get1stHandshakeLock(ss);
if (ss->opt.enableFalseStart ||
(ss->opt.enable0RttData && !ss->sec.isServer)) {
ssl_GetSSL3HandshakeLock(ss);
/* The client can sometimes send before the handshake is fully
* complete. In TLS 1.2: false start; in TLS 1.3: 0-RTT. */
- falseStart = ss->ssl3.hs.canFalseStart ||
- ss->ssl3.hs.zeroRttState == ssl_0rtt_sent ||
- ss->ssl3.hs.zeroRttState == ssl_0rtt_accepted;
+ zeroRtt = ss->ssl3.hs.zeroRttState == ssl_0rtt_sent ||
+ ss->ssl3.hs.zeroRttState == ssl_0rtt_accepted;
+ allowEarlySend = ss->ssl3.hs.canFalseStart || zeroRtt;
ssl_ReleaseSSL3HandshakeLock(ss);
}
- if (!falseStart && ss->handshake) {
+ if (!allowEarlySend && ss->handshake) {
rv = ssl_Do1stHandshake(ss);
}
ssl_Release1stHandshakeLock(ss);
@@ -945,6 +947,20 @@ ssl_SecureSend(sslSocket *ss, const unsigned char *buf, int len, int flags)
goto done;
}
+ if (zeroRtt) {
+ /* There's a limit to the number of early data octets we can send.
+ *
+ * Note that taking this lock doesn't prevent the cipher specs from
+ * being changed out between here and when records are ultimately
+ * encrypted. The only effect of that is to occasionally do an
+ * unnecessary short write when data is identified as 0-RTT here but
+ * 1-RTT later.
+ */
+ ssl_GetSpecReadLock(ss);
+ len = tls13_LimitEarlyData(ss, content_application_data, len);
+ ssl_ReleaseSpecReadLock(ss);
+ }
+
/* Check for zero length writes after we do housekeeping so we make forward
* progress.
*/
@@ -959,19 +975,6 @@ ssl_SecureSend(sslSocket *ss, const unsigned char *buf, int len, int flags)
goto done;
}
- if (!ss->firstHsDone) {
-#ifdef DEBUG
- ssl_GetSSL3HandshakeLock(ss);
- PORT_Assert(!ss->sec.isServer &&
- (ss->ssl3.hs.canFalseStart ||
- ss->ssl3.hs.zeroRttState == ssl_0rtt_sent ||
- ss->ssl3.hs.zeroRttState == ssl_0rtt_accepted));
- ssl_ReleaseSSL3HandshakeLock(ss);
-#endif
- SSL_TRC(3, ("%d: SSL[%d]: SecureSend: sending data due to false start",
- SSL_GETPID(), ss->fd));
- }
-
ssl_GetXmitBufLock(ss);
rv = ssl3_SendApplicationData(ss, buf, len, flags);
ssl_ReleaseXmitBufLock(ss);
@@ -994,6 +997,42 @@ ssl_SecureWrite(sslSocket *ss, const unsigned char *buf, int len)
}
SECStatus
+SSL_AlertReceivedCallback(PRFileDesc *fd, SSLAlertCallback cb, void *arg)
+{
+ sslSocket *ss;
+
+ ss = ssl_FindSocket(fd);
+ if (!ss) {
+ SSL_DBG(("%d: SSL[%d]: unable to find socket in SSL_AlertReceivedCallback",
+ SSL_GETPID(), fd));
+ return SECFailure;
+ }
+
+ ss->alertReceivedCallback = cb;
+ ss->alertReceivedCallbackArg = arg;
+
+ return SECSuccess;
+}
+
+SECStatus
+SSL_AlertSentCallback(PRFileDesc *fd, SSLAlertCallback cb, void *arg)
+{
+ sslSocket *ss;
+
+ ss = ssl_FindSocket(fd);
+ if (!ss) {
+ SSL_DBG(("%d: SSL[%d]: unable to find socket in SSL_AlertSentCallback",
+ SSL_GETPID(), fd));
+ return SECFailure;
+ }
+
+ ss->alertSentCallback = cb;
+ ss->alertSentCallbackArg = arg;
+
+ return SECSuccess;
+}
+
+SECStatus
SSL_BadCertHook(PRFileDesc *fd, SSLBadCertHandler f, void *arg)
{
sslSocket *ss;