Commit 0328af0b authored by Martin Thomson's avatar Martin Thomson

Bug 1350602 - TLS 1.3 draft-19 - CertificateRequest, r=ekr

I ended up changing the extension handler function a little to deal
with messages that allow unknown extensions better.  I also changed
tls13_ExtensionAllowed to only deal with those extensions that TLS 1.3
cares about.  We now don't send point formats in TLS 1.3; I considered
doing the same for renegotiation info, but decided against it.

Differential Revision: https://nss-review.dev.mozaws.net/D280

--HG--
branch : NSS_TLS13_DRAFT19_BRANCH
extra : rebase_source : 41533ac1e794b11925fc3b8b0f9424700fdc0f8b
parent 1fe699b7
......@@ -1037,12 +1037,16 @@ class TlsBogusExtensionTest13 : public TlsBogusExtensionTest {
return;
}
FailWithAlert(kTlsAlertUnsupportedExtension);
}
void FailWithAlert(uint8_t alert) {
client_->StartConnect();
server_->StartConnect();
client_->Handshake(); // ClientHello
server_->Handshake(); // ServerHello
client_->ExpectSendAlert(kTlsAlertUnsupportedExtension);
client_->ExpectSendAlert(alert);
client_->Handshake();
if (mode_ == STREAM) {
server_->ExpectSendAlert(kTlsAlertBadRecordMac);
......@@ -1067,9 +1071,12 @@ TEST_P(TlsBogusExtensionTest13, AddBogusExtensionCertificate) {
Run(kTlsHandshakeCertificate);
}
// It's perfectly valid to set unknown extensions in CertificateRequest.
TEST_P(TlsBogusExtensionTest13, AddBogusExtensionCertificateRequest) {
server_->RequestClientAuth(false);
Run(kTlsHandshakeCertificateRequest);
AddFilter(kTlsHandshakeCertificateRequest, 0xff);
FailWithAlert(kTlsAlertDecryptError);
client_->CheckErrorCode(SEC_ERROR_BAD_SIGNATURE);
}
TEST_P(TlsBogusExtensionTest13, AddBogusExtensionHelloRetryRequest) {
......
......@@ -448,13 +448,6 @@ static bool FindCertReqExtensions(TlsParser* parser,
if (!parser->SkipVariable(1)) { // request context
return false;
}
// TODO remove the next two for -19
if (!parser->SkipVariable(2)) { // signature_algorithms
return false;
}
if (!parser->SkipVariable(2)) { // certificate_authorities
return false;
}
return true;
}
......
......@@ -6442,8 +6442,8 @@ ssl3_PickServerSignatureScheme(sslSocket *ss)
/* Sets error code, if needed. */
return ssl_PickSignatureScheme(ss, keyPair->pubKey, keyPair->privKey,
ss->xtnData.clientSigSchemes,
ss->xtnData.numClientSigScheme,
ss->xtnData.sigSchemes,
ss->xtnData.numSigSchemes,
PR_FALSE /* requireSha1 */);
}
......@@ -7303,7 +7303,7 @@ typedef struct dnameNode {
*/
SECStatus
ssl3_ParseCertificateRequestCAs(sslSocket *ss, SSL3Opaque **b, PRUint32 *length,
PLArenaPool *arena, CERTDistNames *ca_list)
CERTDistNames *ca_list)
{
PRUint32 remaining;
int nnames = 0;
......@@ -7318,7 +7318,7 @@ ssl3_ParseCertificateRequestCAs(sslSocket *ss, SSL3Opaque **b, PRUint32 *length,
if (remaining > *length)
goto alert_loser;
ca_list->head = node = PORT_ArenaZNew(arena, dnameNode);
ca_list->head = node = PORT_ArenaZNew(ca_list->arena, dnameNode);
if (node == NULL)
goto no_mem;
......@@ -7344,14 +7344,14 @@ ssl3_ParseCertificateRequestCAs(sslSocket *ss, SSL3Opaque **b, PRUint32 *length,
if (remaining <= 0)
break; /* success */
node->next = PORT_ArenaZNew(arena, dnameNode);
node->next = PORT_ArenaZNew(ca_list->arena, dnameNode);
node = node->next;
if (node == NULL)
goto no_mem;
}
ca_list->nnames = nnames;
ca_list->names = PORT_ArenaNewArray(arena, SECItem, nnames);
ca_list->names = PORT_ArenaNewArray(ca_list->arena, SECItem, nnames);
if (nnames > 0 && ca_list->names == NULL)
goto no_mem;
......@@ -7495,7 +7495,7 @@ ssl3_HandleCertificateRequest(sslSocket *ss, SSL3Opaque *b, PRUint32 length)
}
}
rv = ssl3_ParseCertificateRequestCAs(ss, &b, &length, arena, &ca_list);
rv = ssl3_ParseCertificateRequestCAs(ss, &b, &length, &ca_list);
if (rv != SECSuccess)
goto done; /* alert sent in ssl3_ParseCertificateRequestCAs */
......@@ -9635,10 +9635,10 @@ ssl3_SendCertificateRequest(sslSocket *ss)
const PRUint8 *certTypes;
SECStatus rv;
int length;
SECItem *names;
const SECItem *names;
unsigned int calen;
unsigned int nnames;
SECItem *name;
const SECItem *name;
int i;
int certTypesLength;
PRUint8 sigAlgs[MAX_SIGNATURE_SCHEMES * 2];
......@@ -10184,8 +10184,8 @@ ssl3_SendEmptyCertificate(sslSocket *ss)
const SECItem *context;
if (ss->version >= SSL_LIBRARY_VERSION_TLS_1_3) {
PORT_Assert(ss->ssl3.hs.certificateRequest);
context = &ss->ssl3.hs.certificateRequest->context;
PORT_Assert(ss->ssl3.hs.clientCertRequested);
context = &ss->xtnData.certReqContext;
len = context->len + 1;
isTLS13 = PR_TRUE;
}
......@@ -10414,8 +10414,8 @@ ssl3_SendCertificate(sslSocket *ss)
if (isTLS13) {
contextLen = 1; /* Size of the context length */
if (!ss->sec.isServer) {
PORT_Assert(ss->ssl3.hs.certificateRequest);
context = ss->ssl3.hs.certificateRequest->context;
PORT_Assert(ss->ssl3.hs.clientCertRequested);
context = ss->xtnData.certReqContext;
contextLen += context.len;
}
}
......@@ -12889,7 +12889,6 @@ ssl3_InitState(sslSocket *ss)
ss->ssl3.hs.serverHsTrafficSecret = NULL;
ss->ssl3.hs.clientTrafficSecret = NULL;
ss->ssl3.hs.serverTrafficSecret = NULL;
ss->ssl3.hs.certificateRequest = NULL;
PR_INIT_CLIST(&ss->ssl3.hs.cipherSpecs);
PORT_Assert(!ss->ssl3.hs.messages.buf && !ss->ssl3.hs.messages.space);
......@@ -13231,11 +13230,6 @@ ssl3_DestroySSL3Info(sslSocket *ss)
SECITEM_FreeItem(&ss->ssl3.hs.newSessionTicket.ticket, PR_FALSE);
SECITEM_FreeItem(&ss->ssl3.hs.srvVirtName, PR_FALSE);
if (ss->ssl3.hs.certificateRequest) {
PORT_FreeArena(ss->ssl3.hs.certificateRequest->arena, PR_FALSE);
ss->ssl3.hs.certificateRequest = NULL;
}
/* free up the CipherSpecs */
ssl3_DestroyCipherSpec(&ss->ssl3.specs[0], PR_TRUE /*freeSrvName*/);
ssl3_DestroyCipherSpec(&ss->ssl3.specs[1], PR_TRUE /*freeSrvName*/);
......
......@@ -31,7 +31,7 @@ static const ssl3ExtensionHandler clientHelloHandlers[] = {
{ ssl_app_layer_protocol_xtn, &ssl3_ServerHandleAppProtoXtn },
{ ssl_use_srtp_xtn, &ssl3_ServerHandleUseSRTPXtn },
{ ssl_cert_status_xtn, &ssl3_ServerHandleStatusRequestXtn },
{ ssl_signature_algorithms_xtn, &ssl3_ServerHandleSigAlgsXtn },
{ ssl_signature_algorithms_xtn, &ssl3_HandleSigAlgsXtn },
{ ssl_extended_master_secret_xtn, &ssl3_HandleExtendedMasterSecretXtn },
{ ssl_signed_cert_timestamp_xtn, &ssl3_ServerHandleSignedCertTimestampXtn },
{ ssl_tls13_key_share_xtn, &tls13_ServerHandleKeyShareXtn },
......@@ -88,6 +88,9 @@ static const ssl3ExtensionHandler serverCertificateHandlers[] = {
};
static const ssl3ExtensionHandler certificateRequestHandlers[] = {
{ ssl_signature_algorithms_xtn, &ssl3_HandleSigAlgsXtn },
{ ssl_tls13_certificate_authorities_xtn,
&tls13_ClientHandleCertAuthoritiesXtn },
{ -1, NULL }
};
......@@ -101,7 +104,7 @@ static const ssl3ExtensionHandler certificateRequestHandlers[] = {
* the client hello is empty (for example, the extended master secret
* extension, if it were listed last). See bug 1243641.
*/
static const ssl3HelloExtensionSender clientHelloSendersTLS[SSL_MAX_EXTENSIONS] =
static const ssl3HelloExtensionSender clientHelloSendersTLS[] =
{
{ ssl_server_name_xtn, &ssl3_SendServerNameXtn },
{ ssl_extended_master_secret_xtn, &ssl3_SendExtendedMasterSecretXtn },
......@@ -122,19 +125,19 @@ static const ssl3HelloExtensionSender clientHelloSendersTLS[SSL_MAX_EXTENSIONS]
* signature_algorithms at the end. See bug 1243641. */
{ ssl_tls13_supported_versions_xtn, &tls13_ClientSendSupportedVersionsXtn },
{ ssl_tls13_short_header_xtn, &tls13_SendShortHeaderXtn },
{ ssl_signature_algorithms_xtn, &ssl3_ClientSendSigAlgsXtn },
{ ssl_signature_algorithms_xtn, &ssl3_SendSigAlgsXtn },
{ ssl_tls13_cookie_xtn, &tls13_ClientSendHrrCookieXtn },
{ ssl_tls13_psk_key_exchange_modes_xtn,
&tls13_ClientSendPskKeyExchangeModesXtn },
{ ssl_padding_xtn, &ssl3_ClientSendPaddingExtension },
/* The pre_shared_key extension MUST be last. */
{ ssl_tls13_pre_shared_key_xtn, &tls13_ClientSendPreSharedKeyXtn },
/* any extra entries will appear as { 0, NULL } */
{ 0, NULL }
};
static const ssl3HelloExtensionSender clientHelloSendersSSL3[SSL_MAX_EXTENSIONS] = {
{ ssl_renegotiation_info_xtn, &ssl3_SendRenegotiationInfoXtn }
/* any extra entries will appear as { 0, NULL } */
static const ssl3HelloExtensionSender clientHelloSendersSSL3[] = {
{ ssl_renegotiation_info_xtn, &ssl3_SendRenegotiationInfoXtn },
{ 0, NULL }
};
static PRBool
......@@ -258,6 +261,11 @@ ssl3_HandleParsedExtensions(sslSocket *ss,
* do so, but we weren't entirely sure. TODO(ekr@rtfm.com). */
PRBool isTLS13 = (ss->version >= SSL_LIBRARY_VERSION_TLS_1_3) ||
(handshakeMessage == hello_retry_request);
/* The following messages can include extensions that were not included in
* the original ClientHello. */
PRBool allowNotOffered = (handshakeMessage == client_hello) ||
(handshakeMessage == certificate_request) ||
(handshakeMessage == new_session_ticket);
PRCList *cursor;
switch (handshakeMessage) {
......@@ -302,25 +310,35 @@ ssl3_HandleParsedExtensions(sslSocket *ss,
const ssl3ExtensionHandler *handler;
/* Check whether the server sent an extension which was not advertised
* in the ClientHello */
if (!ss->sec.isServer &&
!ssl3_ClientExtensionAdvertised(ss, extension->type) &&
(handshakeMessage != new_session_ticket) &&
(extension->type != ssl_tls13_cookie_xtn)) {
* in the ClientHello.
*
* Note that a TLS 1.3 server should check if CertificateRequest
* extensions were sent. But the extensions used for CertificateRequest
* do not have any response, so we rely on
* ssl3_ClientExtensionAdvertised to return false on the server. That
* results in the server only rejecting any extension. */
if (!allowNotOffered && (extension->type != ssl_tls13_cookie_xtn) &&
!ssl3_ClientExtensionAdvertised(ss, extension->type)) {
(void)SSL3_SendAlert(ss, alert_fatal, unsupported_extension);
PORT_SetError(SSL_ERROR_RX_UNEXPECTED_EXTENSION);
return SECFailure;
}
/* Check that this is a legal extension in TLS 1.3 */
if (isTLS13 && !tls13_ExtensionAllowed(extension->type, handshakeMessage)) {
if (handshakeMessage == client_hello) {
/* Skip extensions not used in TLS 1.3 */
continue;
if (isTLS13) {
switch (tls13_ExtensionStatus(extension->type, handshakeMessage)) {
case tls13_extension_allowed:
break;
case tls13_extension_unknown:
if (allowNotOffered) {
continue; /* Skip over unknown extensions. */
}
/* Fall through. */
case tls13_extension_disallowed:
tls13_FatalError(ss, SSL_ERROR_EXTENSION_DISALLOWED_FOR_VERSION,
unsupported_extension);
return SECFailure;
}
tls13_FatalError(ss, SSL_ERROR_EXTENSION_DISALLOWED_FOR_VERSION,
unsupported_extension);
return SECFailure;
}
/* Special check for this being the last extension if it's
......@@ -350,6 +368,7 @@ ssl3_HandleParsedExtensions(sslSocket *ss,
}
return SECFailure;
}
break;
}
}
}
......@@ -390,14 +409,21 @@ ssl3_RegisterExtensionSender(const sslSocket *ss,
if (ss->version < SSL_LIBRARY_VERSION_TLS_1_3) {
sender = &xtnData->serverHelloSenders[0];
} else {
if (tls13_ExtensionAllowed(ex_type, server_hello)) {
PORT_Assert(!tls13_ExtensionAllowed(ex_type, encrypted_extensions));
if (tls13_ExtensionStatus(ex_type, server_hello) ==
tls13_extension_allowed) {
PORT_Assert(tls13_ExtensionStatus(ex_type, encrypted_extensions) ==
tls13_extension_disallowed);
sender = &xtnData->serverHelloSenders[0];
} else if (tls13_ExtensionAllowed(ex_type, certificate)) {
} else if (tls13_ExtensionStatus(ex_type, encrypted_extensions) ==
tls13_extension_allowed) {
sender = &xtnData->encryptedExtensionsSenders[0];
} else if (tls13_ExtensionStatus(ex_type, certificate) ==
tls13_extension_allowed) {
sender = &xtnData->certificateSenders[0];
} else {
PORT_Assert(tls13_ExtensionAllowed(ex_type, encrypted_extensions));
sender = &xtnData->encryptedExtensionsSenders[0];
PORT_Assert(0);
PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
return SECFailure;
}
}
for (i = 0; i < SSL_MAX_EXTENSIONS; ++i, ++sender) {
......@@ -424,7 +450,6 @@ ssl3_CallHelloExtensionSenders(sslSocket *ss, PRBool append, PRUint32 maxBytes,
const ssl3HelloExtensionSender *sender)
{
PRInt32 total_exten_len = 0;
int i;
if (!sender) {
if (ss->vrange.max > SSL_LIBRARY_VERSION_3_0) {
......@@ -434,14 +459,14 @@ ssl3_CallHelloExtensionSenders(sslSocket *ss, PRBool append, PRUint32 maxBytes,
}
}
for (i = 0; i < SSL_MAX_EXTENSIONS; ++i, ++sender) {
if (sender->ex_sender) {
PRInt32 extLen = (*sender->ex_sender)(ss, &ss->xtnData, append, maxBytes);
if (extLen < 0)
return -1;
maxBytes -= extLen;
total_exten_len += extLen;
while (sender->ex_sender) {
PRInt32 extLen = (*sender->ex_sender)(ss, &ss->xtnData, append, maxBytes);
if (extLen < 0) {
return -1;
}
maxBytes -= extLen;
total_exten_len += extLen;
++sender;
}
return total_exten_len;
}
......@@ -475,9 +500,14 @@ ssl3_ResetExtensionData(TLSExtensionData *xtnData)
{
/* Clean up. */
ssl3_FreeSniNameArray(xtnData);
PORT_Free(xtnData->clientSigSchemes);
PORT_Free(xtnData->sigSchemes);
SECITEM_FreeItem(&xtnData->nextProto, PR_FALSE);
tls13_DestroyKeyShares(&xtnData->remoteKeyShares);
SECITEM_FreeItem(&xtnData->certReqContext, PR_FALSE);
if (xtnData->certReqAuthorities.arena) {
PORT_FreeArena(xtnData->certReqAuthorities.arena, PR_FALSE);
xtnData->certReqAuthorities.arena = NULL;
}
/* Now reinit. */
ssl3_InitExtensionData(xtnData);
......
......@@ -86,10 +86,13 @@ struct TLSExtensionDataStr {
PRBool peerSupportsFfdheGroups; /* if the peer supports named ffdhe groups */
/* clientSigAndHash contains the contents of the signature_algorithms
* extension (if any) from the client. This is only valid for TLS 1.2
* or later. */
SSLSignatureScheme *clientSigSchemes;
unsigned int numClientSigScheme;
* extension (if any) the other side supports. This is only valid for TLS
* 1.2 or later. In TLS 1.3, it is also used for CertificateRequest. */
SSLSignatureScheme *sigSchemes;
unsigned int numSigSchemes;
SECItem certReqContext;
CERTDistNames certReqAuthorities;
/* In a client: if the server supports Next Protocol Negotiation, then
* this is the protocol that was negotiated.
......
......@@ -380,6 +380,8 @@ SECStatus
ssl3_ServerHandleNextProtoNegoXtn(const sslSocket *ss, TLSExtensionData *xtnData, PRUint16 ex_type,
SECItem *data)
{
PORT_Assert(ss->version < SSL_LIBRARY_VERSION_TLS_1_3);
if (ss->firstHsDone || data->len != 0) {
/* Clients MUST send an empty NPN extension, if any. */
PORT_SetError(SSL_ERROR_NEXT_PROTOCOL_DATA_INVALID);
......@@ -521,6 +523,7 @@ SECStatus
ssl3_ClientHandleNextProtoNegoXtn(const sslSocket *ss, TLSExtensionData *xtnData, PRUint16 ex_type,
SECItem *data)
{
PORT_Assert(ss->version < SSL_LIBRARY_VERSION_TLS_1_3);
PORT_Assert(!ss->firstHsDone);
if (ssl3_ExtensionNegotiated(ss, ssl_app_layer_protocol_xtn)) {
......@@ -1276,6 +1279,8 @@ SECStatus
ssl3_ClientHandleSessionTicketXtn(const sslSocket *ss, TLSExtensionData *xtnData, PRUint16 ex_type,
SECItem *data)
{
PORT_Assert(ss->version < SSL_LIBRARY_VERSION_TLS_1_3);
if (data->len != 0) {
return SECSuccess; /* Ignore the extension. */
}
......@@ -1740,6 +1745,7 @@ SECStatus
ssl3_ServerHandleSessionTicketXtn(const sslSocket *ss, TLSExtensionData *xtnData, PRUint16 ex_type,
SECItem *data)
{
PORT_Assert(ss->version < SSL_LIBRARY_VERSION_TLS_1_3);
/* Ignore the SessionTicket extension if processing is disabled. */
if (!ss->opt.enableSessionTickets) {
......@@ -1839,11 +1845,14 @@ ssl3_SendRenegotiationInfoXtn(
/* This function runs in both the client and server. */
SECStatus
ssl3_HandleRenegotiationInfoXtn(const sslSocket *ss, TLSExtensionData *xtnData, PRUint16 ex_type, SECItem *data)
ssl3_HandleRenegotiationInfoXtn(const sslSocket *ss, TLSExtensionData *xtnData,
PRUint16 ex_type, SECItem *data)
{
SECStatus rv = SECSuccess;
PRUint32 len = 0;
PORT_Assert(ss->version < SSL_LIBRARY_VERSION_TLS_1_3);
if (ss->firstHsDone) {
len = ss->sec.isServer ? ss->ssl3.hs.finishedBytes
: ss->ssl3.hs.finishedBytes * 2;
......@@ -2092,11 +2101,12 @@ ssl3_ServerHandleUseSRTPXtn(const sslSocket *ss, TLSExtensionData *xtnData, PRUi
ssl3_ServerSendUseSRTPXtn);
}
/* ssl3_ServerHandleSigAlgsXtn handles the signature_algorithms extension
* from a client.
* See https://tools.ietf.org/html/rfc5246#section-7.4.1.4.1 */
/* ssl3_HandleSigAlgsXtn handles the signature_algorithms extension from a
* client. In TLS 1.3, the client uses this to parse CertificateRequest
* extensions. See https://tools.ietf.org/html/rfc5246#section-7.4.1.4.1 */
SECStatus
ssl3_ServerHandleSigAlgsXtn(const sslSocket *ss, TLSExtensionData *xtnData, PRUint16 ex_type, SECItem *data)
ssl3_HandleSigAlgsXtn(const sslSocket *ss, TLSExtensionData *xtnData,
PRUint16 ex_type, SECItem *data)
{
SECStatus rv;
......@@ -2105,15 +2115,15 @@ ssl3_ServerHandleSigAlgsXtn(const sslSocket *ss, TLSExtensionData *xtnData, PRUi
return SECSuccess;
}
if (xtnData->clientSigSchemes) {
PORT_Free(xtnData->clientSigSchemes);
xtnData->clientSigSchemes = NULL;
if (xtnData->sigSchemes) {
PORT_Free(xtnData->sigSchemes);
xtnData->sigSchemes = NULL;
}
rv = ssl_ParseSignatureSchemes(ss, NULL,
&xtnData->clientSigSchemes,
&xtnData->numClientSigScheme,
&xtnData->sigSchemes,
&xtnData->numSigSchemes,
&data->data, &data->len);
if (rv != SECSuccess || xtnData->numClientSigScheme == 0) {
if (rv != SECSuccess || xtnData->numSigSchemes == 0) {
ssl3_ExtSendAlert(ss, alert_fatal, decode_error);
PORT_SetError(SSL_ERROR_RX_MALFORMED_CLIENT_HELLO);
return SECFailure;
......@@ -2133,7 +2143,8 @@ ssl3_ServerHandleSigAlgsXtn(const sslSocket *ss, TLSExtensionData *xtnData, PRUi
/* ssl3_ClientSendSigAlgsXtn sends the signature_algorithm extension for TLS
* 1.2 ClientHellos. */
PRInt32
ssl3_ClientSendSigAlgsXtn(const sslSocket *ss, TLSExtensionData *xtnData, PRBool append, PRUint32 maxBytes)
ssl3_SendSigAlgsXtn(const sslSocket *ss, TLSExtensionData *xtnData,
PRBool append, PRUint32 maxBytes)
{
PRInt32 extension_length;
PRUint8 buf[MAX_SIGNATURE_SCHEMES * 2];
......@@ -2297,6 +2308,8 @@ SECStatus
ssl3_HandleExtendedMasterSecretXtn(const sslSocket *ss, TLSExtensionData *xtnData, PRUint16 ex_type,
SECItem *data)
{
PORT_Assert(ss->version < SSL_LIBRARY_VERSION_TLS_1_3);
if (ss->version < SSL_LIBRARY_VERSION_TLS_1_0) {
return SECSuccess;
}
......@@ -2448,6 +2461,8 @@ ssl3_HandleSupportedPointFormatsXtn(const sslSocket *ss, TLSExtensionData *xtnDa
{
int i;
PORT_Assert(ss->version < SSL_LIBRARY_VERSION_TLS_1_3);
if (data->len < 2 || data->len > 255 || !data->data ||
data->len != (unsigned int)data->data[0] + 1) {
ssl3_ExtDecodeError(ss);
......
......@@ -44,10 +44,10 @@ SECStatus ssl3_ClientHandleStatusRequestXtn(const sslSocket *ss, TLSExtensionDat
SECItem *data);
PRInt32 ssl3_ClientSendStatusRequestXtn(const sslSocket *ss, TLSExtensionData *xtnData, PRBool append,
PRUint32 maxBytes);
PRInt32 ssl3_ClientSendSigAlgsXtn(const sslSocket *ss, TLSExtensionData *xtnData, PRBool append,
PRUint32 maxBytes);
SECStatus ssl3_ServerHandleSigAlgsXtn(const sslSocket *ss, TLSExtensionData *xtnData, PRUint16 ex_type,
SECItem *data);
PRInt32 ssl3_SendSigAlgsXtn(const sslSocket *ss, TLSExtensionData *xtnData,
PRBool append, PRUint32 maxBytes);
SECStatus ssl3_HandleSigAlgsXtn(const sslSocket *ss, TLSExtensionData *xtnData,
PRUint16 ex_type, SECItem *data);
PRInt32 ssl3_ClientSendPaddingExtension(const sslSocket *ss, TLSExtensionData *xtnData,
PRBool append, PRUint32 maxBytes);
......
......@@ -46,7 +46,7 @@ ssl_SetupCAListOnce(void *arg)
}
SECStatus
ssl_SetupCAList(sslSocket *ss)
ssl_SetupCAList(const sslSocket *ss)
{
if (PR_SUCCESS != PR_CallOnceWithArg(&ssl_server_ca_list.setup,
&ssl_SetupCAListOnce,
......@@ -58,11 +58,11 @@ ssl_SetupCAList(sslSocket *ss)
}
SECStatus
ssl_GetCertificateRequestCAs(sslSocket *ss, unsigned int *calen,
SECItem **names, unsigned int *nnames)
ssl_GetCertificateRequestCAs(const sslSocket *ss, unsigned int *calen,
const SECItem **names, unsigned int *nnames)
{
SECItem *name;
CERTDistNames *ca_list;
const SECItem *name;
const CERTDistNames *ca_list;
unsigned int i;
*calen = 0;
......
......@@ -760,15 +760,6 @@ typedef enum {
handshake_hash_record
} SSL3HandshakeHashType;
/* This holds state for TLS 1.3 CertificateRequest handling. */
typedef struct TLS13CertificateRequestStr {
PLArenaPool *arena;
SECItem context;
SSLSignatureScheme *signatureSchemes;
unsigned int signatureSchemeCount;
CERTDistNames ca_list;
} TLS13CertificateRequest;
/*
** This is the "hs" member of the "ssl3" struct.
** This entire struct is protected by ssl3HandshakeLock
......@@ -869,20 +860,19 @@ typedef struct SSL3HandshakeStateStr {
PK11SymKey *serverTrafficSecret; /* traffic keys */
PK11SymKey *earlyExporterSecret; /* for 0-RTT exporters */
PK11SymKey *exporterSecret; /* for exporters */
/* The certificate request from the server. */
TLS13CertificateRequest *certificateRequest;
PRCList cipherSpecs; /* The cipher specs in the sequence they
PRCList cipherSpecs; /* The cipher specs in the sequence they
* will be applied. */
sslZeroRttState zeroRttState; /* Are we doing a 0-RTT handshake? */
sslZeroRttIgnore zeroRttIgnore; /* Are we ignoring 0-RTT? */
ssl3CipherSuite zeroRttSuite; /* The cipher suite we used for 0-RTT. */
PRCList bufferedEarlyData; /* Buffered TLS 1.3 early data
sslZeroRttState zeroRttState; /* Are we doing a 0-RTT handshake? */
sslZeroRttIgnore zeroRttIgnore; /* Are we ignoring 0-RTT? */
ssl3CipherSuite zeroRttSuite; /* The cipher suite we used for 0-RTT. */
PRCList bufferedEarlyData; /* Buffered TLS 1.3 early data
* on server.*/
PRBool helloRetry; /* True if HelloRetryRequest has been sent
PRBool helloRetry; /* True if HelloRetryRequest has been sent
* or received. */
ssl3KEADef kea_def_mutable; /* Used to hold the writable kea_def
PRBool clientCertRequested; /* True if CertificateRequest received. */
ssl3KEADef kea_def_mutable; /* Used to hold the writable kea_def
* we use for TLS 1.3 */
PRBool shortHeaders; /* Assigned if we are doing short headers. */
PRBool shortHeaders; /* Assigned if we are doing short headers. */
} SSL3HandshakeState;
/*
......@@ -1792,11 +1782,12 @@ SECStatus ssl_ReadCertificateStatus(sslSocket *ss, SSL3Opaque *b,
PRUint32 length);
SECStatus ssl3_EncodeSigAlgs(const sslSocket *ss, PRUint8 *buf,
unsigned maxLen, PRUint32 *len);
SECStatus ssl_GetCertificateRequestCAs(sslSocket *ss, unsigned int *calenp,
SECItem **namesp, unsigned int *nnamesp);
SECStatus ssl_GetCertificateRequestCAs(const sslSocket *ss,
unsigned int *calenp,
const SECItem **namesp,
unsigned int *nnamesp);
SECStatus ssl3_ParseCertificateRequestCAs(sslSocket *ss, SSL3Opaque **b,
PRUint32 *length, PLArenaPool *arena,
CERTDistNames *ca_list);
PRUint32 *length, CERTDistNames *ca_list);
SECStatus ssl3_CompleteHandleCertificateRequest(
sslSocket *ss, const SSLSignatureScheme *signatureSchemes,
unsigned int signatureSchemeCount, CERTDistNames *ca_list);
......
......@@ -402,6 +402,7 @@ typedef enum {
ssl_tls13_cookie_xtn = 44,
ssl_tls13_psk_key_exchange_modes_xtn = 45,
ssl_tls13_ticket_early_data_info_xtn = 46, /* Deprecated. */
ssl_tls13_certificate_authorities_xtn = 47,
ssl_next_proto_nego_xtn = 13172,
ssl_renegotiation_info_xtn = 0xff01,
ssl_tls13_short_header_xtn = 0xff03
......
This diff is collapsed.
......@@ -14,6 +14,12 @@ typedef enum {
EphemeralSharedSecret
} SharedSecretType;
typedef enum {
tls13_extension_allowed,
tls13_extension_disallowed,
tls13_extension_unknown
} tls13ExtensionStatus;
#define TLS13_MAX_FINISHED_SIZE 64
SECStatus tls13_UnprotectRecord(
......@@ -76,7 +82,8 @@ void tls13_DestroyEarlyData(PRCList *list);
void tls13_CipherSpecAddRef(ssl3CipherSpec *spec);
void tls13_CipherSpecRelease(ssl3CipherSpec *spec);
void tls13_DestroyCipherSpecs(PRCList *list);
PRBool tls13_ExtensionAllowed(PRUint16 extension, SSL3HandshakeType message);
tls13ExtensionStatus tls13_ExtensionStatus(PRUint16 extension,
SSL3HandshakeType message);
SECStatus tls13_ProtectRecord(sslSocket *ss,
ssl3CipherSpec *cwSpec,
SSL3ContentType type,
......
......@@ -1185,3 +1185,97 @@ tls13_HandleShortHeaderXtn(
return SECSuccess;
}
PRInt32
tls13_SendCertAuthoritiesXtn(const sslSocket *ss, TLSExtensionData *xtnData,
PRBool append, PRUint32 maxBytes)
{
unsigned int extensionLen;
unsigned int calen;
const SECItem *name;
unsigned int nnames;
SECStatus rv;
PORT_Assert(ss->version >= SSL_LIBRARY_VERSION_TLS_1_3);
rv = ssl_GetCertificateRequestCAs(ss, &calen, &name, &nnames);
if (rv != SECSuccess) {
return -1;
}
if (!calen) {
return 0;
}
extensionLen = 2 + 2 + 2 + calen; /* type, length, inner length, CA list */
if (maxBytes < extensionLen) {
PORT_Assert(0);
return 0;
}
if (append) {
rv = ssl3_ExtAppendHandshakeNumber(ss, ssl_tls13_certificate_authorities_xtn, 2);
if (rv != SECSuccess) {
return -1;
}
rv = ssl3_ExtAppendHandshakeNumber(ss, calen + 2, 2);
if (rv != SECSuccess) {
return -1;
}
rv = ssl3_ExtAppendHandshakeNumber(ss, calen, 2);
if (rv != SECSuccess) {
return -1;
}
while (nnames) {
rv = ssl3_ExtAppendHandshakeVariable(ss, name->data, name->len, 2);
if (rv != SECSuccess) {
return -1;
}
++name;
--nnames;
}
}
return extensionLen;
}
SECStatus
tls13_ClientHandleCertAuthoritiesXtn(const sslSocket *ss,
TLSExtensionData *xtnData,
PRUint16 ex_type, SECItem *data)
{
SECStatus rv;
PLArenaPool *arena;
if (!data->len) {
ssl3_ExtSendAlert(ss, alert_fatal, decode_error);
PORT_SetError(SSL_ERROR_RX_MALFORMED_CERT_REQUEST);
return SECFailure;
}
arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
if (!arena) {
PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
return SECFailure;
}
xtnData->certReqAuthorities.arena = arena;
rv = ssl3_ParseCertificateRequestCAs((sslSocket *)ss,
&data->data, &data->len,
&xtnData->certReqAuthorities);
if (rv != SECSuccess) {
goto loser;
}
if (data->len) {
ssl3_ExtSendAlert(ss, alert_fatal, decode_error);
PORT_SetError(SSL_ERROR_RX_MALFORMED_CERT_REQUEST);
goto loser;
}
return SECSuccess;
loser:
PORT_FreeArena(arena, PR_FALSE);
xtnData->certReqAuthorities.arena = NULL;
return SECFailure;
}
......@@ -71,4 +71,11 @@ SECStatus tls13_HandleShortHeaderXtn(
const sslSocket *ss, TLSExtensionData *xtnData, PRUint16 ex_type,
SECItem *data);
PRInt32 tls13_SendCertAuthoritiesXtn(const sslSocket *ss,
TLSExtensionData *xtnData,
PRBool append, PRUint32 maxBytes);
SECStatus tls13_ClientHandleCertAuthoritiesXtn(const sslSocket *ss,
TLSExtensionData *xtnData,
PRUint16 ex_type, SECItem *data);
#endif
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment