Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Bug 1306869 - draft-16 changes to HelloRetryRequest, r=ekr
--HG--
extra : rebase_source : dccae949b19a19d7f92323b53b32057adec3419c
  • Loading branch information
martinthomson committed Sep 30, 2016
1 parent f661099 commit 725184d
Show file tree
Hide file tree
Showing 5 changed files with 91 additions and 44 deletions.
10 changes: 6 additions & 4 deletions external_tests/ssl_gtest/ssl_hrr_unittest.cc
Expand Up @@ -189,11 +189,13 @@ class HelloRetryRequestAgentTest : public TlsAgentTestClient {
SSL_LIBRARY_VERSION_TLS_1_3 >> 8,
SSL_LIBRARY_VERSION_TLS_1_3 & 0xff,
0,
0, // The cipher suite is ignored.
static_cast<uint8_t>(group >> 8),
static_cast<uint8_t>(group),
6, // length of extensions
static_cast<uint8_t>(ssl_tls13_key_share_xtn >> 8),
static_cast<uint8_t>(ssl_tls13_key_share_xtn),
0,
0 // no extensions
2, // length of key share extension
static_cast<uint8_t>(group >> 8),
static_cast<uint8_t>(group)
};
DataBuffer hrr;
MakeHandshakeMessage(kTlsHandshakeHelloRetryRequest, canned_hrr,
Expand Down
55 changes: 55 additions & 0 deletions lib/ssl/ssl3ext.c
Expand Up @@ -96,6 +96,9 @@ static PRInt32 tls13_ClientSendKeyShareXtn(sslSocket *ss, PRBool append,
static SECStatus tls13_ClientHandleKeyShareXtn(sslSocket *ss,
PRUint16 ex_type,
SECItem *data);
static SECStatus tls13_ClientHandleKeyShareXtnHrr(sslSocket *ss,
PRUint16 ex_type,
SECItem *data);
static SECStatus tls13_ServerHandleKeyShareXtn(sslSocket *ss,
PRUint16 ex_type,
SECItem *data);
Expand Down Expand Up @@ -287,6 +290,11 @@ static const ssl3ExtensionHandler serverHelloHandlersTLS[] = {
{ -1, NULL }
};

static const ssl3ExtensionHandler helloRetryRequestHandlers[] = {
{ ssl_tls13_key_share_xtn, tls13_ClientHandleKeyShareXtnHrr },
{ -1, NULL }
};

static const ssl3ExtensionHandler serverHelloHandlersSSL3[] = {
{ ssl_renegotiation_info_xtn, &ssl3_HandleRenegotiationInfoXtn },
{ -1, NULL }
Expand Down Expand Up @@ -2165,6 +2173,10 @@ ssl3_HandleParsedExtensions(sslSocket *ss,
PORT_Assert(ss->version >= SSL_LIBRARY_VERSION_TLS_1_3);
handlers = newSessionTicketHandlers;
break;
case hello_retry_request:
PORT_Assert(ss->version >= SSL_LIBRARY_VERSION_TLS_1_3);
handlers = helloRetryRequestHandlers;
break;
case encrypted_extensions:
PORT_Assert(ss->version >= SSL_LIBRARY_VERSION_TLS_1_3);
/* fall through */
Expand Down Expand Up @@ -3170,6 +3182,49 @@ tls13_ClientHandleKeyShareXtn(sslSocket *ss, PRUint16 ex_type, SECItem *data)
return SECSuccess;
}

static SECStatus
tls13_ClientHandleKeyShareXtnHrr(sslSocket *ss, PRUint16 ex_type, SECItem *data)
{
SECStatus rv;
PRInt32 tmp;
const sslNamedGroupDef *group;

PORT_Assert(!ss->sec.isServer);
PORT_Assert(ss->version >= SSL_LIBRARY_VERSION_TLS_1_3);

SSL_TRC(3, ("%d: SSL3[%d]: handle key_share extension in HRR",
SSL_GETPID(), ss->fd));

tmp = ssl3_ConsumeHandshakeNumber(ss, 2, &data->data, &data->len);
if (tmp < 0) {
return SECFailure; /* error code already set */
}
if (data->len) {
(void)SSL3_SendAlert(ss, alert_fatal, decode_error);
PORT_SetError(SSL_ERROR_RX_MALFORMED_HELLO_RETRY_REQUEST);
return SECFailure;
}

group = ssl_LookupNamedGroup((SSLNamedGroup)tmp);
/* If the group is not enabled, or we already have a share for the
* requested group, abort. */
if (!ssl_NamedGroupEnabled(ss, group) ||
ssl_LookupEphemeralKeyPair(ss, group)) {
(void)SSL3_SendAlert(ss, alert_fatal, illegal_parameter);
PORT_SetError(SSL_ERROR_RX_MALFORMED_HELLO_RETRY_REQUEST);
return SECFailure;
}

rv = tls13_CreateKeyShare(ss, group);
if (rv != SECSuccess) {
(void)SSL3_SendAlert(ss, alert_fatal, internal_error);
PORT_SetError(SEC_ERROR_KEYGEN_FAIL);
return SECFailure;
}

return SECSuccess;
}

/* Handle an incoming KeyShare extension at the server and copy to
* |ss->ssl3.hs.remoteKeyShares| for future use. The key
* share is processed in tls13_HandleClientKeyShare(). */
Expand Down
7 changes: 5 additions & 2 deletions lib/ssl/sslt.h
Expand Up @@ -325,8 +325,11 @@ typedef enum {
/* This is the old name for the supported_groups extensions. */
#define ssl_elliptic_curves_xtn ssl_supported_groups_xtn

#define SSL_MAX_EXTENSIONS 16 /* doesn't include ssl_padding_xtn or \
* TLS 1.3 NewSessionTicket extensions. */
/* SSL_MAX_EXTENSIONS doesn't include ssl_padding_xtn. It includes the maximum
* number of extensions that are supported for any single message type. That
* is, a ClientHello; ServerHello and TLS 1.3 NewSessionTicket and
* HelloRetryRequest extensions are smaller. */
#define SSL_MAX_EXTENSIONS 16

/* Deprecated */
typedef enum {
Expand Down
62 changes: 24 additions & 38 deletions lib/ssl/tls13con.c
Expand Up @@ -1405,9 +1405,10 @@ tls13_SendHelloRetryRequest(sslSocket *ss, const sslNamedGroupDef *selectedGroup
ssl_GetXmitBufLock(ss);
rv = ssl3_AppendHandshakeHeader(ss, hello_retry_request,
2 + /* version */
2 + /* cipher suite */
2 + /* group */
2 /* (empty) extensions */);
2 + /* extension length */
2 + /* group extension id */
2 + /* group extension length */
2 /* group */);
if (rv != SECSuccess) {
FATAL_ERROR(ss, SEC_ERROR_LIBRARY_FAILURE, internal_error);
goto loser;
Expand All @@ -1420,20 +1421,26 @@ tls13_SendHelloRetryRequest(sslSocket *ss, const sslNamedGroupDef *selectedGroup
goto loser;
}

rv = ssl3_AppendHandshakeNumber(ss, ss->ssl3.hs.cipher_suite, 2);
/* Length of extensions. */
rv = ssl3_AppendHandshakeNumber(ss, 2 + 2 + 2, 2);
if (rv != SECSuccess) {
FATAL_ERROR(ss, SEC_ERROR_LIBRARY_FAILURE, internal_error);
goto loser;
}

rv = ssl3_AppendHandshakeNumber(ss, selectedGroup->name, 2);
/* Key share extension - currently the only reason we send this. */
rv = ssl3_AppendHandshakeNumber(ss, ssl_tls13_key_share_xtn, 2);
if (rv != SECSuccess) {
FATAL_ERROR(ss, SEC_ERROR_LIBRARY_FAILURE, internal_error);
goto loser;
}

/* Send an empty extensions block. */
rv = ssl3_AppendHandshakeNumber(ss, 0, 2);
/* Key share extension length. */
rv = ssl3_AppendHandshakeNumber(ss, 2, 2);
if (rv != SECSuccess) {
FATAL_ERROR(ss, SEC_ERROR_LIBRARY_FAILURE, internal_error);
goto loser;
}
rv = ssl3_AppendHandshakeNumber(ss, selectedGroup->name, 2);
if (rv != SECSuccess) {
FATAL_ERROR(ss, SEC_ERROR_LIBRARY_FAILURE, internal_error);
goto loser;
Expand Down Expand Up @@ -1608,7 +1615,6 @@ tls13_HandleHelloRetryRequest(sslSocket *ss, SSL3Opaque *b, PRUint32 length)
SECStatus rv;
PRInt32 tmp;
PRUint32 version;
const sslNamedGroupDef *group;

SSL_TRC(3, ("%d: TLS13[%d]: handle hello retry request",
SSL_GETPID(), ss->fd));
Expand Down Expand Up @@ -1649,45 +1655,19 @@ tls13_HandleHelloRetryRequest(sslSocket *ss, SSL3Opaque *b, PRUint32 length)
return SECFailure;
}

/* Ignore the cipher suite, it's going to be removed soon anyway. */
tmp = ssl3_ConsumeHandshakeNumber(ss, 2, &b, &length);
if (tmp < 0) {
return SECFailure; /* error code already set */
}

tmp = ssl3_ConsumeHandshakeNumber(ss, 2, &b, &length);
if (tmp < 0) {
return SECFailure; /* error code already set */
}
group = ssl_LookupNamedGroup((SSLNamedGroup)tmp);
if (!ssl_NamedGroupEnabled(ss, group)) {
FATAL_ERROR(ss, SSL_ERROR_RX_MALFORMED_HELLO_RETRY_REQUEST,
illegal_parameter);
return SECFailure;
}

tmp = ssl3_ConsumeHandshakeNumber(ss, 2, &b, &length);
if (tmp < 0) {
return SECFailure; /* error code already set */
}
/* Ignore the extensions. */
if (tmp != length) {
FATAL_ERROR(ss, SSL_ERROR_RX_MALFORMED_HELLO_RETRY_REQUEST,
decode_error);
return SECFailure;
}

/* If there is already a share for the requested group, abort. */
if (ssl_LookupEphemeralKeyPair(ss, group)) {
FATAL_ERROR(ss, SSL_ERROR_RX_MALFORMED_HELLO_RETRY_REQUEST,
illegal_parameter);
return SECFailure;
}

rv = tls13_CreateKeyShare(ss, group);
rv = ssl3_HandleExtensions(ss, &b, &length, hello_retry_request);
if (rv != SECSuccess) {
FATAL_ERROR(ss, SEC_ERROR_KEYGEN_FAIL, internal_error);
return SECFailure;
return SECFailure; /* Error code set below */
}

ss->ssl3.hs.helloRetry = PR_TRUE;
Expand Down Expand Up @@ -3718,6 +3698,7 @@ typedef enum {
ExtensionNotUsed,
ExtensionClientOnly,
ExtensionSendClear,
ExtensionSendClearOrHrr,
ExtensionSendEncrypted,
ExtensionNewSessionTicket
} Tls13ExtensionStatus;
Expand All @@ -3735,7 +3716,7 @@ static const struct {
{ ssl_padding_xtn, ExtensionNotUsed },
{ ssl_extended_master_secret_xtn, ExtensionNotUsed },
{ ssl_session_ticket_xtn, ExtensionClientOnly },
{ ssl_tls13_key_share_xtn, ExtensionSendClear },
{ ssl_tls13_key_share_xtn, ExtensionSendClearOrHrr },
{ ssl_tls13_pre_shared_key_xtn, ExtensionSendClear },
{ ssl_tls13_early_data_xtn, ExtensionSendEncrypted },
{ ssl_next_proto_nego_xtn, ExtensionNotUsed },
Expand All @@ -3752,6 +3733,7 @@ tls13_ExtensionAllowed(PRUint16 extension, SSL3HandshakeType message)

PORT_Assert((message == client_hello) ||
(message == server_hello) ||
(message == hello_retry_request) ||
(message == encrypted_extensions) ||
(message == new_session_ticket));

Expand All @@ -3773,6 +3755,10 @@ tls13_ExtensionAllowed(PRUint16 extension, SSL3HandshakeType message)
case ExtensionSendClear:
return message == client_hello ||
message == server_hello;
case ExtensionSendClearOrHrr:
return message == client_hello ||
message == server_hello ||
message == hello_retry_request;
case ExtensionSendEncrypted:
return message == client_hello ||
message == encrypted_extensions;
Expand Down
1 change: 1 addition & 0 deletions lib/ssl/tls13con.h
Expand Up @@ -52,6 +52,7 @@ SECStatus tls13_HandlePostHelloHandshakeMessage(sslSocket *ss, SSL3Opaque *b,
SSL3Hashes *hashesPtr);
void tls13_DestroyKeyShareEntry(TLS13KeyShareEntry *entry);
void tls13_DestroyKeyShares(PRCList *list);
SECStatus tls13_CreateKeyShare(sslSocket *ss, const sslNamedGroupDef *groupDef);
void tls13_DestroyEarlyData(PRCList *list);
void tls13_CipherSpecAddRef(ssl3CipherSpec *spec);
void tls13_CipherSpecRelease(ssl3CipherSpec *spec);
Expand Down

0 comments on commit 725184d

Please sign in to comment.