Skip to content

Commit

Permalink
Bug 1427556 - API for setting max_early_data_size, r=ekr
Browse files Browse the repository at this point in the history
Summary:
We had an API for this in tests, but this formalizes it.  Note that we
can't use SSL_OptionSet here, but I decided to use the structures.

Reviewers: ekr

Subscribers: mcmanus

Bug #: 1427556

Differential Revision: https://phabricator.services.mozilla.com/D344

--HG--
extra : rebase_source : 2dbe5e99bec16f6c524e88aea9ba8f0ab3d29f84
extra : amend_source : a412f988fdcc5a7be49061c2d493cc8079110df9
  • Loading branch information
martinthomson committed Jan 22, 2018
1 parent 78966f8 commit 121a9dd
Show file tree
Hide file tree
Showing 10 changed files with 64 additions and 41 deletions.
4 changes: 0 additions & 4 deletions gtests/ssl_gtest/libssl_internals.c
Expand Up @@ -332,10 +332,6 @@ void SSLInt_SetTicketLifetime(uint32_t lifetime) {
ssl_ticket_lifetime = lifetime;
}

void SSLInt_SetMaxEarlyDataSize(uint32_t size) {
ssl_max_early_data_size = size;
}

SECStatus SSLInt_SetSocketMaxEarlyDataSize(PRFileDesc *fd, uint32_t size) {
sslSocket *ss;

Expand Down
1 change: 0 additions & 1 deletion gtests/ssl_gtest/libssl_internals.h
Expand Up @@ -50,7 +50,6 @@ PK11SymKey *SSLInt_CipherSpecToKey(const ssl3CipherSpec *spec);
SSLCipherAlgorithm SSLInt_CipherSpecToAlgorithm(const ssl3CipherSpec *spec);
const PRUint8 *SSLInt_CipherSpecToIv(const ssl3CipherSpec *spec);
void SSLInt_SetTicketLifetime(uint32_t lifetime);
void SSLInt_SetMaxEarlyDataSize(uint32_t size);
SECStatus SSLInt_SetSocketMaxEarlyDataSize(PRFileDesc *fd, uint32_t size);
void SSLInt_RolloverAntiReplay(void);

Expand Down
9 changes: 7 additions & 2 deletions gtests/ssl_gtest/ssl_0rtt_unittest.cc
Expand Up @@ -459,10 +459,13 @@ static void CheckEarlyDataLimit(const std::shared_ptr<TlsAgent>& agent,
}

TEST_P(TlsConnectTls13, SendTooMuchEarlyData) {
EnsureTlsSetup();
const char* big_message = "0123456789abcdef";
const size_t short_size = strlen(big_message) - 1;
const PRInt32 short_length = static_cast<PRInt32>(short_size);
SSLInt_SetMaxEarlyDataSize(static_cast<PRUint32>(short_size));
EXPECT_EQ(SECSuccess,
SSL_SetMaxEarlyDataSize(server_->ssl_fd(),
static_cast<PRUint32>(short_size)));
SetupForZeroRtt();

client_->Set0RttEnabled(true);
Expand Down Expand Up @@ -514,8 +517,10 @@ TEST_P(TlsConnectTls13, SendTooMuchEarlyData) {
}

TEST_P(TlsConnectTls13, ReceiveTooMuchEarlyData) {
EnsureTlsSetup();

const size_t limit = 5;
SSLInt_SetMaxEarlyDataSize(limit);
EXPECT_EQ(SECSuccess, SSL_SetMaxEarlyDataSize(server_->ssl_fd(), limit));
SetupForZeroRtt();

client_->Set0RttEnabled(true);
Expand Down
4 changes: 4 additions & 0 deletions gtests/ssl_gtest/tls_agent.cc
Expand Up @@ -183,6 +183,10 @@ bool TlsAgent::EnsureTlsSetup(PRFileDesc* modelSocket) {
ScopedCERTCertList anchors(CERT_NewCertList());
rv = SSL_SetTrustAnchors(ssl_fd(), anchors.get());
if (rv != SECSuccess) return false;

rv = SSL_SetMaxEarlyDataSize(ssl_fd(), 1024);
EXPECT_EQ(SECSuccess, rv);
if (rv != SECSuccess) return false;
} else {
rv = SSL_SetURL(ssl_fd(), "server");
EXPECT_EQ(SECSuccess, rv);
Expand Down
1 change: 0 additions & 1 deletion gtests/ssl_gtest/tls_connect.cc
Expand Up @@ -197,7 +197,6 @@ void TlsConnectTestBase::SetUp() {
SSL_ConfigServerSessionIDCache(1024, 0, 0, g_working_dir_path.c_str());
SSLInt_ClearSelfEncryptKey();
SSLInt_SetTicketLifetime(30);
SSLInt_SetMaxEarlyDataSize(1024);
SSL_SetupAntiReplay(1 * PR_USEC_PER_SEC, 1, 3);
ClearStats();
Init();
Expand Down
2 changes: 1 addition & 1 deletion lib/ssl/ssl3exthandle.c
Expand Up @@ -821,7 +821,7 @@ ssl3_EncodeSessionTicket(sslSocket *ss, const NewSessionTicket *ticket,
if (rv != SECSuccess)
goto loser;

rv = sslBuffer_AppendNumber(&plaintext, ssl_max_early_data_size, 4);
rv = sslBuffer_AppendNumber(&plaintext, ss->opt.maxEarlyDataSize, 4);
if (rv != SECSuccess)
goto loser;

Expand Down
8 changes: 8 additions & 0 deletions lib/ssl/sslexp.h
Expand Up @@ -444,6 +444,14 @@ typedef SECStatus(PR_CALLBACK *SSLResumptionTokenCallback)(
(PRFileDesc * _fd, const PRUint8 *_token, const unsigned int _len), \
(fd, token, len))

/* TLS 1.3 allows a server to set a limit on the number of bytes of early data
* that can be received. This allows that limit to be set. This function has no
* effect on a client. */
#define SSL_SetMaxEarlyDataSize(fd, size) \
SSL_EXPERIMENTAL_API("SSL_SetMaxEarlyDataSize", \
(PRFileDesc * _fd, PRUint32 _size), \
(fd, size))

/* Deprecated experimental APIs */

#define SSL_UseAltServerHelloType(fd, enable) SSL_DEPRECATED_EXPERIMENTAL_API
Expand Down
2 changes: 1 addition & 1 deletion lib/ssl/sslimpl.h
Expand Up @@ -233,6 +233,7 @@ typedef struct sslOptionsStr {
* list of supported protocols. */
SECItem nextProtoNego;

PRUint32 maxEarlyDataSize;
unsigned int useSecurity : 1;
unsigned int useSocks : 1;
unsigned int requestCertificate : 1;
Expand Down Expand Up @@ -1069,7 +1070,6 @@ extern FILE *ssl_keylog_iob;
extern PZLock *ssl_keylog_lock;
extern PRUint32 ssl3_sid_timeout;
extern PRUint32 ssl_ticket_lifetime;
extern PRUint32 ssl_max_early_data_size;

extern const char *const ssl3_cipherName[];

Expand Down
70 changes: 42 additions & 28 deletions lib/ssl/sslsock.c
Expand Up @@ -53,34 +53,35 @@ static const sslSocketOps ssl_secure_ops = { /* SSL. */
** default settings for socket enables
*/
static sslOptions ssl_defaults = {
{ siBuffer, NULL, 0 }, /* nextProtoNego */
PR_TRUE, /* useSecurity */
PR_FALSE, /* useSocks */
PR_FALSE, /* requestCertificate */
2, /* requireCertificate */
PR_FALSE, /* handshakeAsClient */
PR_FALSE, /* handshakeAsServer */
PR_FALSE, /* noCache */
PR_FALSE, /* fdx */
PR_TRUE, /* detectRollBack */
PR_FALSE, /* noLocks */
PR_FALSE, /* enableSessionTickets */
PR_FALSE, /* enableDeflate */
2, /* enableRenegotiation (default: requires extension) */
PR_FALSE, /* requireSafeNegotiation */
PR_FALSE, /* enableFalseStart */
PR_TRUE, /* cbcRandomIV */
PR_FALSE, /* enableOCSPStapling */
PR_FALSE, /* enableNPN */
PR_TRUE, /* enableALPN */
PR_TRUE, /* reuseServerECDHEKey */
PR_FALSE, /* enableFallbackSCSV */
PR_TRUE, /* enableServerDhe */
PR_FALSE, /* enableExtendedMS */
PR_FALSE, /* enableSignedCertTimestamps */
PR_FALSE, /* requireDHENamedGroups */
PR_FALSE, /* enable0RttData */
PR_FALSE /* enableTls13CompatMode */
.nextProtoNego = { siBuffer, NULL, 0 },
.maxEarlyDataSize = 1 << 16,
.useSecurity = PR_TRUE,
.useSocks = PR_FALSE,
.requestCertificate = PR_FALSE,
.requireCertificate = SSL_REQUIRE_FIRST_HANDSHAKE,
.handshakeAsClient = PR_FALSE,
.handshakeAsServer = PR_FALSE,
.noCache = PR_FALSE,
.fdx = PR_FALSE,
.detectRollBack = PR_TRUE,
.noLocks = PR_FALSE,
.enableSessionTickets = PR_FALSE,
.enableDeflate = PR_FALSE,
.enableRenegotiation = SSL_RENEGOTIATE_REQUIRES_XTN,
.requireSafeNegotiation = PR_FALSE,
.enableFalseStart = PR_FALSE,
.cbcRandomIV = PR_TRUE,
.enableOCSPStapling = PR_FALSE,
.enableNPN = PR_FALSE,
.enableALPN = PR_TRUE,
.reuseServerECDHEKey = PR_TRUE,
.enableFallbackSCSV = PR_FALSE,
.enableServerDhe = PR_TRUE,
.enableExtendedMS = PR_FALSE,
.enableSignedCertTimestamps = PR_FALSE,
.requireDHENamedGroups = PR_FALSE,
.enable0RttData = PR_FALSE,
.enableTls13CompatMode = PR_FALSE
};

/*
Expand Down Expand Up @@ -1252,6 +1253,18 @@ SSL_OptionSetDefault(PRInt32 which, PRIntn val)
return SECSuccess;
}

SECStatus
SSLExp_SetMaxEarlyDataSize(PRFileDesc *fd, PRUint32 size)
{
sslSocket *ss = ssl_FindSocket(fd);
if (!ss) {
return SECFailure; /* Error code already set. */
}

ss->opt.maxEarlyDataSize = size;
return SECSuccess;
}

/* function tells us if the cipher suite is one that we no longer support. */
static PRBool
ssl_IsRemovedCipherSuite(PRInt32 suite)
Expand Down Expand Up @@ -3932,6 +3945,7 @@ struct {
EXP(InstallExtensionHooks),
EXP(KeyUpdate),
EXP(SendSessionTicket),
EXP(SetMaxEarlyDataSize),
EXP(SetupAntiReplay),
EXP(SetResumptionTokenCallback),
EXP(SetResumptionToken),
Expand Down
4 changes: 1 addition & 3 deletions lib/ssl/tls13con.c
Expand Up @@ -4417,8 +4417,6 @@ tls13_SendClientSecondRound(sslSocket *ss)
* } NewSessionTicket;
*/

PRUint32 ssl_max_early_data_size = (2 << 16); /* Arbitrary limit. */

static SECStatus
tls13_SendNewSessionTicket(sslSocket *ss, const PRUint8 *appToken,
unsigned int appTokenLen)
Expand Down Expand Up @@ -4520,7 +4518,7 @@ tls13_SendNewSessionTicket(sslSocket *ss, const PRUint8 *appToken,
if (rv != SECSuccess)
goto loser;

rv = ssl3_AppendHandshakeNumber(ss, ssl_max_early_data_size, 4);
rv = ssl3_AppendHandshakeNumber(ss, ss->opt.maxEarlyDataSize, 4);
if (rv != SECSuccess)
goto loser;
}
Expand Down

0 comments on commit 121a9dd

Please sign in to comment.