diff --git a/gtests/ssl_gtest/libssl_internals.c b/gtests/ssl_gtest/libssl_internals.c index 5f923cf400..b763945773 100644 --- a/gtests/ssl_gtest/libssl_internals.c +++ b/gtests/ssl_gtest/libssl_internals.c @@ -179,12 +179,12 @@ SECStatus SSLInt_Set0RttAlpn(PRFileDesc *fd, PRUint8 *data, unsigned int len) { return SECFailure; } - ss->ssl3.nextProtoState = SSL_NEXT_PROTO_EARLY_VALUE; - if (ss->ssl3.nextProto.data) { - SECITEM_FreeItem(&ss->ssl3.nextProto, PR_FALSE); + ss->xtnData.nextProtoState = SSL_NEXT_PROTO_EARLY_VALUE; + if (ss->xtnData.nextProto.data) { + SECITEM_FreeItem(&ss->xtnData.nextProto, PR_FALSE); } - if (!SECITEM_AllocItem(NULL, &ss->ssl3.nextProto, len)) return SECFailure; - PORT_Memcpy(ss->ssl3.nextProto.data, data, len); + if (!SECITEM_AllocItem(NULL, &ss->xtnData.nextProto, len)) return SECFailure; + PORT_Memcpy(ss->xtnData.nextProto.data, data, len); return SECSuccess; } diff --git a/gtests/ssl_gtest/ssl_extension_unittest.cc b/gtests/ssl_gtest/ssl_extension_unittest.cc index 04a1d976a5..43c9868f7d 100644 --- a/gtests/ssl_gtest/ssl_extension_unittest.cc +++ b/gtests/ssl_gtest/ssl_extension_unittest.cc @@ -154,6 +154,25 @@ class TlsExtensionTestBase : public TlsConnectTestBase { extension->Write(3, namelen, 2); extension->Write(5, reinterpret_cast(name), namelen); } + + void HrrThenRemoveExtensionsTest(SSLExtensionType type, PRInt32 client_error, + PRInt32 server_error) { + static const std::vector client_groups = { + ssl_grp_ec_secp384r1, ssl_grp_ec_curve25519}; + static const std::vector server_groups = { + ssl_grp_ec_curve25519, ssl_grp_ec_secp384r1}; + client_->ConfigNamedGroups(client_groups); + server_->ConfigNamedGroups(server_groups); + EnsureTlsSetup(); + client_->StartConnect(); + server_->StartConnect(); + client_->Handshake(); // Send ClientHello + server_->Handshake(); // Send HRR. + client_->SetPacketFilter(new TlsExtensionDropper(type)); + Handshake(); + client_->CheckErrorCode(client_error); + server_->CheckErrorCode(server_error); + } }; class TlsExtensionTestDtls : public TlsExtensionTestBase, @@ -772,6 +791,24 @@ TEST_P(TlsExtensionTest13, RemoveTls13FromVersionListBothV12) { #endif } +TEST_P(TlsExtensionTest13, HrrThenRemoveSignatureAlgorithms) { + HrrThenRemoveExtensionsTest(ssl_signature_algorithms_xtn, + SSL_ERROR_MISSING_EXTENSION_ALERT, + SSL_ERROR_MISSING_SIGNATURE_ALGORITHMS_EXTENSION); +} + +TEST_P(TlsExtensionTest13, HrrThenRemoveKeyShare) { + HrrThenRemoveExtensionsTest(ssl_tls13_key_share_xtn, + SSL_ERROR_ILLEGAL_PARAMETER_ALERT, + SSL_ERROR_BAD_2ND_CLIENT_HELLO); +} + +TEST_P(TlsExtensionTest13, HrrThenRemoveSupportedGroups) { + HrrThenRemoveExtensionsTest(ssl_supported_groups_xtn, + SSL_ERROR_MISSING_EXTENSION_ALERT, + SSL_ERROR_MISSING_SUPPORTED_GROUPS_EXTENSION); +} + TEST_P(TlsExtensionTest13, EmptyVersionList) { static const uint8_t ext[] = {0x00, 0x00}; ConnectWithBogusVersionList(ext, sizeof(ext)); diff --git a/lib/ssl/ssl3con.c b/lib/ssl/ssl3con.c index e03e0238b0..148a17b24f 100644 --- a/lib/ssl/ssl3con.c +++ b/lib/ssl/ssl3con.c @@ -19,6 +19,8 @@ #include "sslimpl.h" #include "sslproto.h" #include "sslerr.h" +#include "ssl3ext.h" +#include "ssl3exthandle.h" #include "prtime.h" #include "prinrval.h" #include "prerror.h" @@ -759,7 +761,8 @@ ssl_LookupCipherSuiteDef(ssl3CipherSuite suite) /* Find the cipher configuration struct associate with suite */ /* XXX This does a linear search. A binary search would be better. */ static ssl3CipherSuiteCfg * -ssl_LookupCipherSuiteCfg(ssl3CipherSuite suite, ssl3CipherSuiteCfg *suites) +ssl_LookupCipherSuiteCfgMutable(ssl3CipherSuite suite, + ssl3CipherSuiteCfg *suites) { int i; @@ -772,6 +775,13 @@ ssl_LookupCipherSuiteCfg(ssl3CipherSuite suite, ssl3CipherSuiteCfg *suites) return NULL; } +const static ssl3CipherSuiteCfg * +ssl_LookupCipherSuiteCfg(ssl3CipherSuite suite, const ssl3CipherSuiteCfg *suites) +{ + return ssl_LookupCipherSuiteCfgMutable(suite, + CONST_CAST(ssl3CipherSuiteCfg, suites)); +} + static PRBool ssl_NamedGroupTypeEnabled(const sslSocket *ss, SSLKEAType keaType) { @@ -803,7 +813,7 @@ ssl_KEAEnabled(const sslSocket *ss, SSLKEAType keaType) * must have included an FFDHE group. peerSupportsFfdheGroups * is set to true in ssl_HandleSupportedGroupsXtn(). */ if (ss->opt.requireDHENamedGroups && - !ss->ssl3.hs.peerSupportsFfdheGroups) { + !ss->xtnData.peerSupportsFfdheGroups) { return PR_FALSE; } @@ -813,7 +823,7 @@ ssl_KEAEnabled(const sslSocket *ss, SSLKEAType keaType) * 3. This isn't TLS 1.3. * 4. The weak group is enabled. */ if (!ss->opt.requireDHENamedGroups && - !ss->ssl3.hs.peerSupportsFfdheGroups && + !ss->xtnData.peerSupportsFfdheGroups && ss->version < SSL_LIBRARY_VERSION_TLS_1_3 && ss->ssl3.dheWeakGroupEnabled) { return PR_TRUE; @@ -4996,7 +5006,7 @@ ssl3_SendClientHello(sslSocket *ss, sslClientHelloType type) PORT_Assert(IS_DTLS(ss) || type != client_hello_retransmit); SECITEM_FreeItem(&ss->ssl3.hs.newSessionTicket.ticket, PR_FALSE); ss->ssl3.hs.receivedNewSessionTicket = PR_FALSE; - PORT_Memset(&ss->xtnData, 0, sizeof(TLSExtensionData)); + ssl3_ResetExtensionData(&ss->xtnData); /* How many suites does our PKCS11 support (regardless of policy)? */ num_suites = ssl3_config_match_init(ss); @@ -6131,27 +6141,27 @@ ssl3_SendRSAClientKeyExchange(sslSocket *ss, SECKEYPublicKey *svrPubKey) /* DH shares need to be padded to the size of their prime. Some implementations * require this. TLS 1.3 also requires this. */ SECStatus -ssl_AppendPaddedDHKeyShare(sslSocket *ss, SECKEYPublicKey *pubKey, +ssl_AppendPaddedDHKeyShare(const sslSocket *ss, const SECKEYPublicKey *pubKey, PRBool appendLength) { SECStatus rv; unsigned int pad = pubKey->u.dh.prime.len - pubKey->u.dh.publicValue.len; if (appendLength) { - rv = ssl3_AppendHandshakeNumber(ss, pubKey->u.dh.prime.len, 2); + rv = ssl3_ExtAppendHandshakeNumber(ss, pubKey->u.dh.prime.len, 2); if (rv != SECSuccess) { return rv; } } while (pad) { - rv = ssl3_AppendHandshakeNumber(ss, 0, 1); + rv = ssl3_ExtAppendHandshakeNumber(ss, 0, 1); if (rv != SECSuccess) { return rv; } --pad; } - rv = ssl3_AppendHandshake(ss, pubKey->u.dh.publicValue.data, - pubKey->u.dh.publicValue.len); + rv = ssl3_ExtAppendHandshake(ss, pubKey->u.dh.publicValue.data, + pubKey->u.dh.publicValue.len); if (rv != SECSuccess) { return rv; } @@ -6196,7 +6206,7 @@ ssl3_SendDHClientKeyExchange(sslSocket *ss, SECKEYPublicKey *svrPubKey) /* If we require named groups, we will have already validated the group * in ssl_HandleDHServerKeyExchange() */ PORT_Assert(!ss->opt.requireDHENamedGroups && - !ss->ssl3.hs.peerSupportsFfdheGroups); + !ss->xtnData.peerSupportsFfdheGroups); customParams.name = ssl_grp_ffdhe_custom; customParams.prime.data = svrPubKey->u.dh.prime.data; @@ -6431,8 +6441,8 @@ ssl3_PickServerSignatureScheme(sslSocket *ss) /* Sets error code, if needed. */ return ssl_PickSignatureScheme(ss, keyPair->pubKey, keyPair->privKey, - ss->ssl3.hs.clientSigSchemes, - ss->ssl3.hs.numClientSigScheme, + ss->xtnData.clientSigSchemes, + ss->xtnData.numClientSigScheme, PR_FALSE /* requireSha1 */); } @@ -7333,7 +7343,7 @@ ssl3_ParseCertificateRequestCAs(sslSocket *ss, SSL3Opaque **b, PRUint32 *length, } SECStatus -ssl_ParseSignatureSchemes(sslSocket *ss, PLArenaPool *arena, +ssl_ParseSignatureSchemes(const sslSocket *ss, PLArenaPool *arena, SSLSignatureScheme **schemesOut, unsigned int *numSchemesOut, unsigned char **b, unsigned int *len) @@ -7344,13 +7354,13 @@ ssl_ParseSignatureSchemes(sslSocket *ss, PLArenaPool *arena, unsigned int numSchemes = 0; unsigned int max; - rv = ssl3_ConsumeHandshakeVariable(ss, &buf, 2, b, len); + rv = ssl3_ExtConsumeHandshakeVariable(ss, &buf, 2, b, len); if (rv != SECSuccess) { return SECFailure; } /* An empty or odd-length value is invalid. */ if (buf.len == 0 || (buf.len & 1) != 0) { - (void)SSL3_SendAlert(ss, alert_fatal, decode_error); + ssl3_ExtSendAlert(ss, alert_fatal, decode_error); return SECFailure; } @@ -7363,13 +7373,13 @@ ssl_ParseSignatureSchemes(sslSocket *ss, PLArenaPool *arena, schemes = PORT_ZNewArray(SSLSignatureScheme, max); } if (!schemes) { - (void)SSL3_SendAlert(ss, alert_fatal, internal_error); + ssl3_ExtSendAlert(ss, alert_fatal, internal_error); return SECFailure; } for (; max; --max) { PRInt32 tmp; - tmp = ssl3_ConsumeHandshakeNumber(ss, 2, &buf.data, &buf.len); + tmp = ssl3_ExtConsumeHandshakeNumber(ss, 2, &buf.data, &buf.len); if (tmp < 0) { PORT_Assert(0); PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); @@ -8157,8 +8167,8 @@ ssl3_ServerCallSNICallback(sslSocket *ss) /* Need to tell the client that application has picked * the name from the offered list and reconfigured the socket. */ - ssl3_RegisterServerHelloExtensionSender(ss, ssl_server_name_xtn, - ssl3_SendServerNameXtn); + ssl3_RegisterExtensionSender(ss, &ss->xtnData, ssl_server_name_xtn, + ssl3_SendServerNameXtn); } else { /* Callback returned index outside of the boundary. */ PORT_Assert((unsigned int)ret < ss->xtnData.sniNameArrSize); @@ -8285,7 +8295,7 @@ ssl3_HandleClientHello(sslSocket *ss, SSL3Opaque *b, PRUint32 length) /* We might be starting session renegotiation in which case we should * clear previous state. */ - PORT_Memset(&ss->xtnData, 0, sizeof(TLSExtensionData)); + ssl3_ResetExtensionData(&ss->xtnData); ss->statelessResume = PR_FALSE; if (IS_DTLS(ss)) { @@ -8943,9 +8953,9 @@ ssl3_HandleClientHelloPart2(sslSocket *ss, */ if (ssl3_ExtensionNegotiated(ss, ssl_session_ticket_xtn) && ssl3_KEASupportsTickets(ss->ssl3.hs.kea_def)) { - ssl3_RegisterServerHelloExtensionSender(ss, - ssl_session_ticket_xtn, - ssl3_SendSessionTicketXtn); + ssl3_RegisterExtensionSender(ss, &ss->xtnData, + ssl_session_ticket_xtn, + ssl3_SendSessionTicketXtn); } rv = ssl3_ServerCallSNICallback(ss); @@ -9041,7 +9051,7 @@ ssl3_HandleV2ClientHello(sslSocket *ss, unsigned char *buffer, int length, ssl_GetSSL3HandshakeLock(ss); - PORT_Memset(&ss->xtnData, 0, sizeof(TLSExtensionData)); + ssl3_ResetExtensionData(&ss->xtnData); version = (buffer[1] << 8) | buffer[2]; if (version < SSL_LIBRARY_VERSION_3_0) { @@ -9540,7 +9550,7 @@ ssl3_SendServerKeyExchange(sslSocket *ss) } SECStatus -ssl3_EncodeSigAlgs(sslSocket *ss, PRUint8 *buf, unsigned maxLen, PRUint32 *len) +ssl3_EncodeSigAlgs(const sslSocket *ss, PRUint8 *buf, unsigned maxLen, PRUint32 *len) { unsigned int i; PRUint8 *p = buf; @@ -11108,24 +11118,24 @@ ssl3_SendNextProto(sslSocket *ss) int padding_len; static const unsigned char padding[32] = { 0 }; - if (ss->ssl3.nextProto.len == 0 || - ss->ssl3.nextProtoState == SSL_NEXT_PROTO_SELECTED) { + if (ss->xtnData.nextProto.len == 0 || + ss->xtnData.nextProtoState == SSL_NEXT_PROTO_SELECTED) { return SECSuccess; } PORT_Assert(ss->opt.noLocks || ssl_HaveXmitBufLock(ss)); PORT_Assert(ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss)); - padding_len = 32 - ((ss->ssl3.nextProto.len + 2) % 32); + padding_len = 32 - ((ss->xtnData.nextProto.len + 2) % 32); - rv = ssl3_AppendHandshakeHeader(ss, next_proto, ss->ssl3.nextProto.len + + rv = ssl3_AppendHandshakeHeader(ss, next_proto, ss->xtnData.nextProto.len + 2 + padding_len); if (rv != SECSuccess) { return rv; /* error code set by AppendHandshakeHeader */ } - rv = ssl3_AppendHandshakeVariable(ss, ss->ssl3.nextProto.data, - ss->ssl3.nextProto.len, 1); + rv = ssl3_AppendHandshakeVariable(ss, ss->xtnData.nextProto.data, + ss->xtnData.nextProto.len, 1); if (rv != SECSuccess) { return rv; /* error code set by AppendHandshake */ } @@ -11535,10 +11545,10 @@ ssl3_FillInCachedSID(sslSocket *ss, sslSessionID *sid) sid->certType.authType = ssl_auth_null; } - if (ss->ssl3.nextProtoState != SSL_NEXT_PROTO_NO_SUPPORT && - ss->ssl3.nextProto.data) { + if (ss->xtnData.nextProtoState != SSL_NEXT_PROTO_NO_SUPPORT && + ss->xtnData.nextProto.data) { if (SECITEM_CopyItem( - NULL, &sid->u.ssl3.alpnSelection, &ss->ssl3.nextProto) != SECSuccess) { + NULL, &sid->u.ssl3.alpnSelection, &ss->xtnData.nextProto) != SECSuccess) { return SECFailure; /* error already set. */ } } @@ -12841,10 +12851,9 @@ ssl3_InitState(sslSocket *ss) ss->ssl3.hs.sendingSCSV = PR_FALSE; ss->ssl3.hs.preliminaryInfo = 0; - ss->ssl3.hs.peerSupportsFfdheGroups = PR_FALSE; ss->ssl3.hs.ws = (ss->sec.isServer) ? wait_client_hello : wait_server_hello; - PORT_Memset(&ss->xtnData, 0, sizeof(TLSExtensionData)); + ssl3_ResetExtensionData(&ss->xtnData); PR_INIT_CLIST(&ss->ssl3.hs.remoteExtensions); if (IS_DTLS(ss)) { ss->ssl3.hs.sendMessageSeq = 0; @@ -12857,7 +12866,6 @@ ssl3_InitState(sslSocket *ss) } ss->ssl3.hs.clientHelloHash = NULL; - PR_INIT_CLIST(&ss->ssl3.hs.remoteKeyShares); ss->ssl3.hs.currentSecret = NULL; ss->ssl3.hs.resumptionPsk = NULL; ss->ssl3.hs.resumptionContext = nullItem; @@ -12892,7 +12900,7 @@ ssl3_SetPolicy(ssl3CipherSuite which, int policy) { ssl3CipherSuiteCfg *suite; - suite = ssl_LookupCipherSuiteCfg(which, cipherSuites); + suite = ssl_LookupCipherSuiteCfgMutable(which, cipherSuites); if (suite == NULL) { return SECFailure; /* err code was set by ssl_LookupCipherSuiteCfg */ } @@ -12904,7 +12912,7 @@ ssl3_SetPolicy(ssl3CipherSuite which, int policy) SECStatus ssl3_GetPolicy(ssl3CipherSuite which, PRInt32 *oPolicy) { - ssl3CipherSuiteCfg *suite; + const ssl3CipherSuiteCfg *suite; PRInt32 policy; SECStatus rv; @@ -12926,7 +12934,7 @@ ssl3_CipherPrefSetDefault(ssl3CipherSuite which, PRBool enabled) { ssl3CipherSuiteCfg *suite; - suite = ssl_LookupCipherSuiteCfg(which, cipherSuites); + suite = ssl_LookupCipherSuiteCfgMutable(which, cipherSuites); if (suite == NULL) { return SECFailure; /* err code was set by ssl_LookupCipherSuiteCfg */ } @@ -12938,7 +12946,7 @@ ssl3_CipherPrefSetDefault(ssl3CipherSuite which, PRBool enabled) SECStatus ssl3_CipherPrefGetDefault(ssl3CipherSuite which, PRBool *enabled) { - ssl3CipherSuiteCfg *suite; + const ssl3CipherSuiteCfg *suite; PRBool pref; SECStatus rv; @@ -12959,7 +12967,7 @@ ssl3_CipherPrefSet(sslSocket *ss, ssl3CipherSuite which, PRBool enabled) { ssl3CipherSuiteCfg *suite; - suite = ssl_LookupCipherSuiteCfg(which, ss->cipherSuites); + suite = ssl_LookupCipherSuiteCfgMutable(which, ss->cipherSuites); if (suite == NULL) { return SECFailure; /* err code was set by ssl_LookupCipherSuiteCfg */ } @@ -12968,9 +12976,9 @@ ssl3_CipherPrefSet(sslSocket *ss, ssl3CipherSuite which, PRBool enabled) } SECStatus -ssl3_CipherPrefGet(sslSocket *ss, ssl3CipherSuite which, PRBool *enabled) +ssl3_CipherPrefGet(const sslSocket *ss, ssl3CipherSuite which, PRBool *enabled) { - ssl3CipherSuiteCfg *suite; + const ssl3CipherSuiteCfg *suite; PRBool pref; SECStatus rv; @@ -13197,9 +13205,6 @@ ssl3_DestroySSL3Info(sslSocket *ss) if (ss->ssl3.hs.sha) { PK11_DestroyContext(ss->ssl3.hs.sha, PR_TRUE); } - if (ss->ssl3.hs.clientSigSchemes) { - PORT_Free(ss->ssl3.hs.clientSigSchemes); - } if (ss->ssl3.hs.messages.buf) { sslBuffer_Clear(&ss->ssl3.hs.messages); } @@ -13229,9 +13234,7 @@ ssl3_DestroySSL3Info(sslSocket *ss) /* Destroy remote extensions */ ssl3_DestroyRemoteExtensions(&ss->ssl3.hs.remoteExtensions); - - /* Destroy TLS 1.3 handshake shares */ - tls13_DestroyKeyShares(&ss->ssl3.hs.remoteKeyShares); + ssl3_ResetExtensionData(&ss->xtnData); /* Destroy the stored hash. */ if (ss->ssl3.hs.clientHelloHash) { @@ -13267,7 +13270,7 @@ ssl3_DestroySSL3Info(sslSocket *ss) ss->ssl3.initialized = PR_FALSE; - SECITEM_FreeItem(&ss->ssl3.nextProto, PR_FALSE); + SECITEM_FreeItem(&ss->xtnData.nextProto, PR_FALSE); } #define MAP_NULL(x) (((x) != 0) ? (x) : SEC_OID_NULL_CIPHER) diff --git a/lib/ssl/ssl3ecc.c b/lib/ssl/ssl3ecc.c index 2595b4cdcb..145083b5e3 100644 --- a/lib/ssl/ssl3ecc.c +++ b/lib/ssl/ssl3ecc.c @@ -18,6 +18,7 @@ #include "sslimpl.h" #include "sslproto.h" #include "sslerr.h" +#include "ssl3ext.h" #include "prtime.h" #include "prinrval.h" #include "prerror.h" @@ -269,14 +270,14 @@ tls13_SizeOfECDHEKeyShareKEX(const SECKEYPublicKey *pubKey) /* This function encodes the key_exchange field in * the KeyShareEntry structure. */ SECStatus -tls13_EncodeECDHEKeyShareKEX(sslSocket *ss, const SECKEYPublicKey *pubKey) +tls13_EncodeECDHEKeyShareKEX(const sslSocket *ss, const SECKEYPublicKey *pubKey) { PORT_Assert(ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss)); PORT_Assert(ss->opt.noLocks || ssl_HaveXmitBufLock(ss)); PORT_Assert(pubKey->keyType == ecKey); - return ssl3_AppendHandshake(ss, pubKey->u.ec.publicValue.data, - pubKey->u.ec.publicValue.len); + return ssl3_ExtAppendHandshake(ss, pubKey->u.ec.publicValue.data, + pubKey->u.ec.publicValue.len); } /* @@ -860,7 +861,7 @@ static const ssl3CipherSuite ssl_dhe_suites[] = { /* Order(N^2). Yuk. */ static PRBool -ssl_IsSuiteEnabled(sslSocket *ss, const ssl3CipherSuite *list) +ssl_IsSuiteEnabled(const sslSocket *ss, const ssl3CipherSuite *list) { const ssl3CipherSuite *suite; @@ -877,7 +878,7 @@ ssl_IsSuiteEnabled(sslSocket *ss, const ssl3CipherSuite *list) /* Ask: is ANY ECC cipher suite enabled on this socket? */ PRBool -ssl_IsECCEnabled(sslSocket *ss) +ssl_IsECCEnabled(const sslSocket *ss) { PK11SlotInfo *slot; @@ -893,14 +894,16 @@ ssl_IsECCEnabled(sslSocket *ss) } PRBool -ssl_IsDHEEnabled(sslSocket *ss) +ssl_IsDHEEnabled(const sslSocket *ss) { return ssl_IsSuiteEnabled(ss, ssl_dhe_suites); } /* Send our Supported Groups extension. */ PRInt32 -ssl_SendSupportedGroupsXtn(sslSocket *ss, PRBool append, PRUint32 maxBytes) +ssl_SendSupportedGroupsXtn(const sslSocket *ss, + TLSExtensionData *xtnData, + PRBool append, PRUint32 maxBytes) { PRInt32 extension_length; unsigned char enabledGroups[64]; @@ -960,18 +963,17 @@ ssl_SendSupportedGroupsXtn(sslSocket *ss, PRBool append, PRUint32 maxBytes) if (append) { SECStatus rv; - rv = ssl3_AppendHandshakeNumber(ss, ssl_supported_groups_xtn, 2); + rv = ssl3_ExtAppendHandshakeNumber(ss, ssl_supported_groups_xtn, 2); if (rv != SECSuccess) return -1; - rv = ssl3_AppendHandshakeNumber(ss, extension_length - 4, 2); + rv = ssl3_ExtAppendHandshakeNumber(ss, extension_length - 4, 2); if (rv != SECSuccess) return -1; - rv = ssl3_AppendHandshakeVariable(ss, enabledGroups, - enabledGroupsLen, 2); + rv = ssl3_ExtAppendHandshakeVariable(ss, enabledGroups, + enabledGroupsLen, 2); if (rv != SECSuccess) return -1; if (!ss->sec.isServer) { - TLSExtensionData *xtnData = &ss->xtnData; xtnData->advertised[xtnData->numAdvertised++] = ssl_supported_groups_xtn; } @@ -984,7 +986,8 @@ ssl_SendSupportedGroupsXtn(sslSocket *ss, PRBool append, PRUint32 maxBytes) */ PRInt32 ssl3_SendSupportedPointFormatsXtn( - sslSocket *ss, + const sslSocket *ss, + TLSExtensionData *xtnData, PRBool append, PRUint32 maxBytes) { @@ -1003,138 +1006,13 @@ ssl3_SendSupportedPointFormatsXtn( (ss->sec.isServer && ss->version >= SSL_LIBRARY_VERSION_TLS_1_3)) return 0; if (append && maxBytes >= (sizeof ecPtFmt)) { - SECStatus rv = ssl3_AppendHandshake(ss, ecPtFmt, (sizeof ecPtFmt)); + SECStatus rv = ssl3_ExtAppendHandshake(ss, ecPtFmt, (sizeof ecPtFmt)); if (rv != SECSuccess) return -1; if (!ss->sec.isServer) { - TLSExtensionData *xtnData = &ss->xtnData; xtnData->advertised[xtnData->numAdvertised++] = ssl_ec_point_formats_xtn; } } return sizeof(ecPtFmt); } - -/* Just make sure that the remote client supports uncompressed points, - * Since that is all we support. Disable ECC cipher suites if it doesn't. - */ -SECStatus -ssl3_HandleSupportedPointFormatsXtn(sslSocket *ss, PRUint16 ex_type, - SECItem *data) -{ - int i; - - if (data->len < 2 || data->len > 255 || !data->data || - data->len != (unsigned int)data->data[0] + 1) { - return ssl3_DecodeError(ss); - } - for (i = data->len; --i > 0;) { - if (data->data[i] == 0) { - /* indicate that we should send a reply */ - SECStatus rv; - rv = ssl3_RegisterServerHelloExtensionSender(ss, ex_type, - &ssl3_SendSupportedPointFormatsXtn); - return rv; - } - } - - /* Poor client doesn't support uncompressed points. */ - PORT_SetError(SSL_ERROR_RX_MALFORMED_HANDSHAKE); - return SECFailure; -} - -static SECStatus -ssl_UpdateSupportedGroups(sslSocket *ss, SECItem *data) -{ - PRInt32 list_len; - unsigned int i; - const sslNamedGroupDef *enabled[SSL_NAMED_GROUP_COUNT] = { 0 }; - PORT_Assert(SSL_NAMED_GROUP_COUNT == PR_ARRAY_SIZE(enabled)); - - if (!data->data || data->len < 4) { - (void)ssl3_DecodeError(ss); - return SECFailure; - } - - /* get the length of elliptic_curve_list */ - list_len = ssl3_ConsumeHandshakeNumber(ss, 2, &data->data, &data->len); - if (list_len < 0 || data->len != list_len || (data->len % 2) != 0) { - (void)ssl3_DecodeError(ss); - return SECFailure; - } - - /* disable all groups and remember the enabled groups */ - for (i = 0; i < SSL_NAMED_GROUP_COUNT; ++i) { - enabled[i] = ss->namedGroupPreferences[i]; - ss->namedGroupPreferences[i] = NULL; - } - - /* Read groups from data and enable if in |enabled| */ - while (data->len) { - const sslNamedGroupDef *group; - PRInt32 curve_name = - ssl3_ConsumeHandshakeNumber(ss, 2, &data->data, &data->len); - if (curve_name < 0) { - return SECFailure; /* fatal alert already sent */ - } - group = ssl_LookupNamedGroup(curve_name); - if (group) { - for (i = 0; i < SSL_NAMED_GROUP_COUNT; ++i) { - if (enabled[i] && group == enabled[i]) { - ss->namedGroupPreferences[i] = enabled[i]; - break; - } - } - } - - /* "Codepoints in the NamedCurve registry with a high byte of 0x01 (that - * is, between 256 and 511 inclusive) are set aside for FFDHE groups," - * -- https://tools.ietf.org/html/draft-ietf-tls-negotiated-ff-dhe-10 - */ - if ((curve_name & 0xff00) == 0x0100) { - ss->ssl3.hs.peerSupportsFfdheGroups = PR_TRUE; - } - } - - /* Note: if ss->opt.requireDHENamedGroups is set, we disable DHE cipher - * suites, but we do that in ssl3_config_match(). */ - if (ss->version < SSL_LIBRARY_VERSION_TLS_1_3 && - !ss->opt.requireDHENamedGroups && !ss->ssl3.hs.peerSupportsFfdheGroups) { - /* If we don't require that DHE use named groups, and no FFDHE was - * included, we pretend that they support all the FFDHE groups we do. */ - for (i = 0; i < SSL_NAMED_GROUP_COUNT; ++i) { - if (enabled[i] && enabled[i]->keaType == ssl_kea_dh) { - ss->namedGroupPreferences[i] = enabled[i]; - } - } - } - - return SECSuccess; -} - -/* Ensure that the curve in our server cert is one of the ones supported - * by the remote client, and disable all ECC cipher suites if not. - */ -SECStatus -ssl_HandleSupportedGroupsXtn(sslSocket *ss, PRUint16 ex_type, SECItem *data) -{ - SECStatus rv; - - rv = ssl_UpdateSupportedGroups(ss, data); - if (rv != SECSuccess) - return SECFailure; - - /* TLS 1.3 permits the server to send this extension so make it so. */ - if (ss->sec.isServer && ss->version >= SSL_LIBRARY_VERSION_TLS_1_3) { - rv = ssl3_RegisterServerHelloExtensionSender(ss, ex_type, - &ssl_SendSupportedGroupsXtn); - if (rv != SECSuccess) { - return SECFailure; /* error already set. */ - } - } - - /* Remember that we negotiated this extension. */ - ss->xtnData.negotiated[ss->xtnData.numNegotiated++] = ex_type; - - return SECSuccess; -} diff --git a/lib/ssl/ssl3ext.c b/lib/ssl/ssl3ext.c index 75f50e835e..d1418fdeee 100644 --- a/lib/ssl/ssl3ext.c +++ b/lib/ssl/ssl3ext.c @@ -130,17 +130,17 @@ arrayContainsExtension(const PRUint16 *array, PRUint32 len, PRUint16 ex_type) } PRBool -ssl3_ExtensionNegotiated(sslSocket *ss, PRUint16 ex_type) +ssl3_ExtensionNegotiated(const sslSocket *ss, PRUint16 ex_type) { - TLSExtensionData *xtnData = &ss->xtnData; + const TLSExtensionData *xtnData = &ss->xtnData; return arrayContainsExtension(xtnData->negotiated, xtnData->numNegotiated, ex_type); } PRBool -ssl3_ClientExtensionAdvertised(sslSocket *ss, PRUint16 ex_type) +ssl3_ClientExtensionAdvertised(const sslSocket *ss, PRUint16 ex_type) { - TLSExtensionData *xtnData = &ss->xtnData; + const TLSExtensionData *xtnData = &ss->xtnData; return arrayContainsExtension(xtnData->advertised, xtnData->numAdvertised, ex_type); } @@ -297,7 +297,8 @@ ssl3_HandleParsedExtensions(sslSocket *ss, if (handler->ex_type == extension->type) { SECStatus rv; - rv = (*handler->ex_handler)(ss, (PRUint16)extension->type, + rv = (*handler->ex_handler)(ss, &ss->xtnData, + (PRUint16)extension->type, &extension->data); if (rv != SECSuccess) { if (!ss->ssl3.fatalAlertSent) { @@ -336,20 +337,22 @@ ssl3_HandleExtensions(sslSocket *ss, /* Add a callback function to the table of senders of server hello extensions. */ SECStatus -ssl3_RegisterServerHelloExtensionSender(sslSocket *ss, PRUint16 ex_type, - ssl3HelloExtensionSenderFunc cb) +ssl3_RegisterExtensionSender(const sslSocket *ss, + TLSExtensionData *xtnData, + PRUint16 ex_type, + ssl3HelloExtensionSenderFunc cb) { int i; ssl3HelloExtensionSender *sender; if (ss->version < SSL_LIBRARY_VERSION_TLS_1_3) { - sender = &ss->xtnData.serverHelloSenders[0]; + sender = &xtnData->serverHelloSenders[0]; } else { if (tls13_ExtensionAllowed(ex_type, server_hello)) { PORT_Assert(!tls13_ExtensionAllowed(ex_type, encrypted_extensions)); - sender = &ss->xtnData.serverHelloSenders[0]; + sender = &xtnData->serverHelloSenders[0]; } else { PORT_Assert(tls13_ExtensionAllowed(ex_type, encrypted_extensions)); - sender = &ss->xtnData.encryptedExtensionsSenders[0]; + sender = &xtnData->encryptedExtensionsSenders[0]; } } @@ -389,7 +392,7 @@ 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, append, maxBytes); + PRInt32 extLen = (*sender->ex_sender)(ss, &ss->xtnData, append, maxBytes); if (extLen < 0) return -1; maxBytes -= extLen; @@ -410,3 +413,86 @@ ssl3_DestroyRemoteExtensions(PRCList *list) PORT_Free(cur_p); } } + +/* Initialize the extension data block. */ +void +ssl3_InitExtensionData(TLSExtensionData *xtnData) +{ + /* Set things up to the right starting state. */ + PORT_Memset(xtnData, 0, sizeof(*xtnData)); + xtnData->peerSupportsFfdheGroups = PR_FALSE; + PR_INIT_CLIST(&xtnData->remoteKeyShares); +} + +/* Free everything that has been allocated and then reset back to + * the starting state. */ +void +ssl3_ResetExtensionData(TLSExtensionData *xtnData) +{ + /* Clean up. */ + ssl3_FreeSniNameArray(xtnData); + PORT_Free(xtnData->clientSigSchemes); + SECITEM_FreeItem(&xtnData->nextProto, PR_FALSE); + tls13_DestroyKeyShares(&xtnData->remoteKeyShares); + + /* Now reinit. */ + ssl3_InitExtensionData(xtnData); +} + +/* Thunks to let extension handlers operate on const sslSocket* objects. */ +SECStatus +ssl3_ExtAppendHandshake(const sslSocket *ss, const void *void_src, + PRInt32 bytes) +{ + return ssl3_AppendHandshake((sslSocket *)ss, void_src, bytes); +} + +SECStatus +ssl3_ExtAppendHandshakeNumber(const sslSocket *ss, PRInt32 num, + PRInt32 lenSize) +{ + return ssl3_AppendHandshakeNumber((sslSocket *)ss, num, lenSize); +} + +SECStatus +ssl3_ExtAppendHandshakeVariable(const sslSocket *ss, + const SSL3Opaque *src, PRInt32 bytes, + PRInt32 lenSize) +{ + return ssl3_AppendHandshakeVariable((sslSocket *)ss, src, bytes, lenSize); +} + +void +ssl3_ExtSendAlert(const sslSocket *ss, SSL3AlertLevel level, + SSL3AlertDescription desc) +{ + (void)SSL3_SendAlert((sslSocket *)ss, level, desc); +} + +void +ssl3_ExtDecodeError(const sslSocket *ss) +{ + (void)ssl3_DecodeError((sslSocket *)ss); +} + +SECStatus +ssl3_ExtConsumeHandshake(const sslSocket *ss, void *v, PRInt32 bytes, + SSL3Opaque **b, PRUint32 *length) +{ + return ssl3_ConsumeHandshake((sslSocket *)ss, v, bytes, b, length); +} + +PRInt32 +ssl3_ExtConsumeHandshakeNumber(const sslSocket *ss, PRInt32 bytes, + SSL3Opaque **b, PRUint32 *length) +{ + return ssl3_ConsumeHandshakeNumber((sslSocket *)ss, bytes, b, length); +} + +SECStatus +ssl3_ExtConsumeHandshakeVariable(const sslSocket *ss, SECItem *i, + PRInt32 bytes, SSL3Opaque **b, + PRUint32 *length) +{ + return ssl3_ConsumeHandshakeVariable((sslSocket *)ss, i, bytes, b, length); +} diff --git a/lib/ssl/ssl3ext.h b/lib/ssl/ssl3ext.h new file mode 100644 index 0000000000..7e1c863d4f --- /dev/null +++ b/lib/ssl/ssl3ext.h @@ -0,0 +1,155 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is PRIVATE to SSL. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef __ssl3ext_h_ +#define __ssl3ext_h_ + +typedef enum { + sni_nametype_hostname +} SNINameType; +typedef struct TLSExtensionDataStr TLSExtensionData; + +/* registerable callback function that either appends extension to buffer + * or returns length of data that it would have appended. + */ +typedef PRInt32 (*ssl3HelloExtensionSenderFunc)(const sslSocket *ss, + TLSExtensionData *xtnData, + PRBool append, + PRUint32 maxBytes); + +/* registerable callback function that handles a received extension, + * of the given type. + */ +typedef SECStatus (*ssl3ExtensionHandlerFunc)(const sslSocket *ss, + TLSExtensionData *xtnData, + PRUint16 ex_type, + SECItem *data); + +/* row in a table of hello extension senders */ +typedef struct { + PRInt32 ex_type; + ssl3HelloExtensionSenderFunc ex_sender; +} ssl3HelloExtensionSender; + +/* row in a table of hello extension handlers */ +typedef struct { + PRInt32 ex_type; + ssl3ExtensionHandlerFunc ex_handler; +} ssl3ExtensionHandler; + +struct TLSExtensionDataStr { + /* registered callbacks that send server hello extensions */ + ssl3HelloExtensionSender serverHelloSenders[SSL_MAX_EXTENSIONS]; + ssl3HelloExtensionSender encryptedExtensionsSenders[SSL_MAX_EXTENSIONS]; + + /* Keep track of the extensions that are negotiated. */ + PRUint16 numAdvertised; + PRUint16 numNegotiated; + PRUint16 advertised[SSL_MAX_EXTENSIONS]; + PRUint16 negotiated[SSL_MAX_EXTENSIONS]; + + /* SessionTicket Extension related data. */ + PRBool ticketTimestampVerified; + PRBool emptySessionTicket; + PRBool sentSessionTicketInClientHello; + SECItem psk_ke_modes; + SECItem psk_auth_modes; + PRUint32 ticket_age_add; + PRBool ticket_age_add_found; + + /* SNI Extension related data + * Names data is not coppied from the input buffer. It can not be + * used outside the scope where input buffer is defined and that + * is beyond ssl3_HandleClientHello function. */ + SECItem *sniNameArr; + PRUint32 sniNameArrSize; + + /* Signed Certificate Timestamps extracted from the TLS extension. + * (client only). + * This container holds a temporary pointer to the extension data, + * until a session structure (the sec.ci.sid of an sslSocket) is setup + * that can hold a permanent copy of the data + * (in sec.ci.sid.u.ssl3.signedCertTimestamps). + * The data pointed to by this structure is neither explicitly allocated + * nor copied: the pointer points to the handshake message buffer and is + * only valid in the scope of ssl3_HandleServerHello. + */ + SECItem signedCertTimestamps; + + 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; + + /* In a client: if the server supports Next Protocol Negotiation, then + * this is the protocol that was negotiated. + */ + SECItem nextProto; + SSLNextProtoState nextProtoState; + + PRUint16 dtlsSRTPCipherSuite; /* 0 if not selected */ + + PRCList remoteKeyShares; /* The other side's public keys (TLS 1.3) */ +}; + +typedef struct TLSExtensionStr { + PRCList link; /* The linked list link */ + PRUint16 type; /* Extension type */ + SECItem data; /* Pointers into the handshake data. */ +} TLSExtension; + +SECStatus ssl3_HandleExtensions(sslSocket *ss, + SSL3Opaque **b, PRUint32 *length, + SSL3HandshakeType handshakeMessage); +SECStatus ssl3_ParseExtensions(sslSocket *ss, + SSL3Opaque **b, PRUint32 *length); +SECStatus ssl3_HandleParsedExtensions(sslSocket *ss, + SSL3HandshakeType handshakeMessage); +TLSExtension *ssl3_FindExtension(sslSocket *ss, + SSLExtensionType extension_type); +void ssl3_DestroyRemoteExtensions(PRCList *list); +void ssl3_InitExtensionData(TLSExtensionData *xtnData); +void ssl3_ResetExtensionData(TLSExtensionData *xtnData); + +PRBool ssl3_ExtensionNegotiated(const sslSocket *ss, PRUint16 ex_type); +PRBool ssl3_ClientExtensionAdvertised(const sslSocket *ss, PRUint16 ex_type); + +SECStatus ssl3_RegisterExtensionSender(const sslSocket *ss, + TLSExtensionData *xtnData, + PRUint16 ex_type, + ssl3HelloExtensionSenderFunc cb); +PRInt32 ssl3_CallHelloExtensionSenders(sslSocket *ss, PRBool append, PRUint32 maxBytes, + const ssl3HelloExtensionSender *sender); + +unsigned int ssl3_CalculatePaddingExtensionLength(unsigned int clientHelloLength); +PRInt32 ssl3_AppendPaddingExtension(sslSocket *ss, unsigned int extensionLen, + PRUint32 maxBytes); + +/* Thunks to let us operate on const sslSocket* objects. */ +SECStatus ssl3_ExtAppendHandshake(const sslSocket *ss, const void *void_src, + PRInt32 bytes); +SECStatus ssl3_ExtAppendHandshakeNumber(const sslSocket *ss, PRInt32 num, + PRInt32 lenSize); +SECStatus ssl3_ExtAppendHandshakeVariable(const sslSocket *ss, + const SSL3Opaque *src, PRInt32 bytes, + PRInt32 lenSize); +void ssl3_ExtSendAlert(const sslSocket *ss, SSL3AlertLevel level, + SSL3AlertDescription desc); +void ssl3_ExtDecodeError(const sslSocket *ss); +SECStatus ssl3_ExtConsumeHandshake(const sslSocket *ss, void *v, PRInt32 bytes, + SSL3Opaque **b, PRUint32 *length); +PRInt32 ssl3_ExtConsumeHandshakeNumber(const sslSocket *ss, PRInt32 bytes, + SSL3Opaque **b, PRUint32 *length); +SECStatus ssl3_ExtConsumeHandshakeVariable(const sslSocket *ss, SECItem *i, + PRInt32 bytes, SSL3Opaque **b, + PRUint32 *length); + +#endif diff --git a/lib/ssl/ssl3exthandle.c b/lib/ssl/ssl3exthandle.c index f1891b9121..b22757a831 100644 --- a/lib/ssl/ssl3exthandle.c +++ b/lib/ssl/ssl3exthandle.c @@ -12,6 +12,7 @@ #include "pk11pub.h" #include "blapit.h" #include "prinit.h" +#include "ssl3ext.h" #include "ssl3exthandle.h" #include "tls13exthandle.h" /* For tls13_ServerSendStatusRequestXtn. */ @@ -30,6 +31,7 @@ static SECStatus ssl3_AppendNumberToItem(SECItem *item, PRUint32 num, PRInt32 lenSize); static SECStatus ssl3_GetSessionTicketKeys(sslSocket *ss, PK11SymKey **aes_key, PK11SymKey **mac_key); +static SECStatus ssl3_ConsumeFromItem(SECItem *item, unsigned char **buf, PRUint32 bytes); /* * Write bytes. Using this function means the SECItem structure @@ -150,12 +152,13 @@ ssl3_GetSessionTicketKeys(sslSocket *ss, PK11SymKey **aes_key, *mac_key = session_ticket_mac_key; return SECSuccess; } + /* Format an SNI extension, using the name from the socket's URL, * unless that name is a dotted decimal string. * Used by client and server. */ PRInt32 -ssl3_SendServerNameXtn(sslSocket *ss, PRBool append, +ssl3_SendServerNameXtn(const sslSocket *ss, TLSExtensionData *xtnData, PRBool append, PRUint32 maxBytes) { SECStatus rv; @@ -176,27 +179,26 @@ ssl3_SendServerNameXtn(sslSocket *ss, PRBool append, len = PORT_Strlen(ss->url); if (append && maxBytes >= len + 9) { /* extension_type */ - rv = ssl3_AppendHandshakeNumber(ss, ssl_server_name_xtn, 2); + rv = ssl3_ExtAppendHandshakeNumber(ss, ssl_server_name_xtn, 2); if (rv != SECSuccess) return -1; /* length of extension_data */ - rv = ssl3_AppendHandshakeNumber(ss, len + 5, 2); + rv = ssl3_ExtAppendHandshakeNumber(ss, len + 5, 2); if (rv != SECSuccess) return -1; /* length of server_name_list */ - rv = ssl3_AppendHandshakeNumber(ss, len + 3, 2); + rv = ssl3_ExtAppendHandshakeNumber(ss, len + 3, 2); if (rv != SECSuccess) return -1; /* Name Type (sni_host_name) */ - rv = ssl3_AppendHandshake(ss, "\0", 1); + rv = ssl3_ExtAppendHandshake(ss, "\0", 1); if (rv != SECSuccess) return -1; /* HostName (length and value) */ - rv = ssl3_AppendHandshakeVariable(ss, (PRUint8 *)ss->url, len, 2); + rv = ssl3_ExtAppendHandshakeVariable(ss, (PRUint8 *)ss->url, len, 2); if (rv != SECSuccess) return -1; if (!ss->sec.isServer) { - TLSExtensionData *xtnData = &ss->xtnData; xtnData->advertised[xtnData->numAdvertised++] = ssl_server_name_xtn; } @@ -205,11 +207,11 @@ ssl3_SendServerNameXtn(sslSocket *ss, PRBool append, } /* Server side */ if (append && maxBytes >= 4) { - rv = ssl3_AppendHandshakeNumber(ss, ssl_server_name_xtn, 2); + rv = ssl3_ExtAppendHandshakeNumber(ss, ssl_server_name_xtn, 2); if (rv != SECSuccess) return -1; /* length of extension_data */ - rv = ssl3_AppendHandshakeNumber(ss, 0, 2); + rv = ssl3_ExtAppendHandshakeNumber(ss, 0, 2); if (rv != SECSuccess) return -1; } @@ -218,10 +220,9 @@ ssl3_SendServerNameXtn(sslSocket *ss, PRBool append, /* Handle an incoming SNI extension. */ SECStatus -ssl3_HandleServerNameXtn(sslSocket *ss, PRUint16 ex_type, SECItem *data) +ssl3_HandleServerNameXtn(const sslSocket *ss, TLSExtensionData *xtnData, PRUint16 ex_type, SECItem *data) { SECItem *names = NULL; - TLSExtensionData *xtnData = &ss->xtnData; PRInt32 listLenBytes = 0; if (!ss->sec.isServer) { @@ -235,7 +236,7 @@ ssl3_HandleServerNameXtn(sslSocket *ss, PRUint16 ex_type, SECItem *data) } /* length of server_name_list */ - listLenBytes = ssl3_ConsumeHandshakeNumber(ss, 2, &data->data, &data->len); + listLenBytes = ssl3_ExtConsumeHandshakeNumber(ss, 2, &data->data, &data->len); if (listLenBytes < 0) { goto loser; /* alert already sent */ } @@ -250,14 +251,14 @@ ssl3_HandleServerNameXtn(sslSocket *ss, PRUint16 ex_type, SECItem *data) PRInt32 type; /* Read Name Type. */ - type = ssl3_ConsumeHandshakeNumber(ss, 1, &data->data, &data->len); + type = ssl3_ExtConsumeHandshakeNumber(ss, 1, &data->data, &data->len); if (type < 0) { /* i.e., SECFailure cast to PRint32 */ /* alert sent in ConsumeHandshakeNumber */ goto loser; } /* Read ServerName (length and value). */ - rv = ssl3_ConsumeHandshakeVariable(ss, &tmp, 2, &data->data, &data->len); + rv = ssl3_ExtConsumeHandshakeVariable(ss, &tmp, 2, &data->data, &data->len); if (rv != SECSuccess) { goto loser; } @@ -296,7 +297,7 @@ ssl3_HandleServerNameXtn(sslSocket *ss, PRUint16 ex_type, SECItem *data) return SECSuccess; alert_loser: - (void)ssl3_DecodeError(ss); + ssl3_ExtDecodeError(ss); loser: if (names) { PORT_Free(names); @@ -329,7 +330,8 @@ ssl3_FreeSniNameArray(TLSExtensionData *xtnData) */ PRInt32 ssl3_SendSessionTicketXtn( - sslSocket *ss, + const sslSocket *ss, + TLSExtensionData *xtnData, PRBool append, PRUint32 maxBytes) { @@ -368,7 +370,7 @@ ssl3_SendSessionTicketXtn( session_ticket = &sid->u.ssl3.locked.sessionTicket; if (session_ticket->ticket.data) { - if (ss->xtnData.ticketTimestampVerified) { + if (xtnData->ticketTimestampVerified) { extension_length += session_ticket->ticket.len; } else if (!append && (session_ticket->ticket_lifetime_hint == 0 || @@ -376,7 +378,7 @@ ssl3_SendSessionTicketXtn( session_ticket->received_timestamp > ssl_Time()))) { extension_length += session_ticket->ticket.len; - ss->xtnData.ticketTimestampVerified = PR_TRUE; + xtnData->ticketTimestampVerified = PR_TRUE; } } } @@ -388,23 +390,22 @@ ssl3_SendSessionTicketXtn( if (append) { SECStatus rv; /* extension_type */ - rv = ssl3_AppendHandshakeNumber(ss, ssl_session_ticket_xtn, 2); + rv = ssl3_ExtAppendHandshakeNumber(ss, ssl_session_ticket_xtn, 2); if (rv != SECSuccess) goto loser; if (session_ticket && session_ticket->ticket.data && - ss->xtnData.ticketTimestampVerified) { - rv = ssl3_AppendHandshakeVariable(ss, session_ticket->ticket.data, - session_ticket->ticket.len, 2); - ss->xtnData.ticketTimestampVerified = PR_FALSE; - ss->xtnData.sentSessionTicketInClientHello = PR_TRUE; + xtnData->ticketTimestampVerified) { + rv = ssl3_ExtAppendHandshakeVariable(ss, session_ticket->ticket.data, + session_ticket->ticket.len, 2); + xtnData->ticketTimestampVerified = PR_FALSE; + xtnData->sentSessionTicketInClientHello = PR_TRUE; } else { - rv = ssl3_AppendHandshakeNumber(ss, 0, 2); + rv = ssl3_ExtAppendHandshakeNumber(ss, 0, 2); } if (rv != SECSuccess) goto loser; if (!ss->sec.isServer) { - TLSExtensionData *xtnData = &ss->xtnData; xtnData->advertised[xtnData->numAdvertised++] = ssl_session_ticket_xtn; } @@ -412,7 +413,7 @@ ssl3_SendSessionTicketXtn( return extension_length; loser: - ss->xtnData.ticketTimestampVerified = PR_FALSE; + xtnData->ticketTimestampVerified = PR_FALSE; return -1; } @@ -444,7 +445,7 @@ ssl3_ParseEncryptedSessionTicket(sslSocket *ss, SECItem *data, /* handle an incoming Next Protocol Negotiation extension. */ SECStatus -ssl3_ServerHandleNextProtoNegoXtn(sslSocket *ss, PRUint16 ex_type, +ssl3_ServerHandleNextProtoNegoXtn(const sslSocket *ss, TLSExtensionData *xtnData, PRUint16 ex_type, SECItem *data) { if (ss->firstHsDone || data->len != 0) { @@ -453,7 +454,7 @@ ssl3_ServerHandleNextProtoNegoXtn(sslSocket *ss, PRUint16 ex_type, return SECFailure; } - ss->xtnData.negotiated[ss->xtnData.numNegotiated++] = ex_type; + xtnData->negotiated[xtnData->numNegotiated++] = ex_type; /* TODO: server side NPN support would require calling * ssl3_RegisterServerHelloExtensionSender here in order to echo the @@ -486,7 +487,8 @@ ssl3_ValidateNextProtoNego(const unsigned char *data, unsigned int length) /* protocol selection handler for ALPN (server side) and NPN (client side) */ static SECStatus -ssl3_SelectAppProtocol(sslSocket *ss, PRUint16 ex_type, SECItem *data) +ssl3_SelectAppProtocol(const sslSocket *ss, TLSExtensionData *xtnData, + PRUint16 ex_type, SECItem *data) { SECStatus rv; unsigned char resultBuffer[255]; @@ -494,7 +496,7 @@ ssl3_SelectAppProtocol(sslSocket *ss, PRUint16 ex_type, SECItem *data) rv = ssl3_ValidateNextProtoNego(data->data, data->len); if (rv != SECSuccess) { - (void)SSL3_SendAlert(ss, alert_fatal, decode_error); + ssl3_ExtSendAlert(ss, alert_fatal, decode_error); PORT_SetError(SSL_ERROR_NEXT_PROTOCOL_DATA_INVALID); return rv; } @@ -509,7 +511,7 @@ ssl3_SelectAppProtocol(sslSocket *ss, PRUint16 ex_type, SECItem *data) result.data, &result.len, sizeof(resultBuffer)); if (rv != SECSuccess) { /* Expect callback to call PORT_SetError() */ - (void)SSL3_SendAlert(ss, alert_fatal, internal_error); + ssl3_ExtSendAlert(ss, alert_fatal, internal_error); return SECFailure; } @@ -521,24 +523,24 @@ ssl3_SelectAppProtocol(sslSocket *ss, PRUint16 ex_type, SECItem *data) return SECFailure; } - SECITEM_FreeItem(&ss->ssl3.nextProto, PR_FALSE); + SECITEM_FreeItem(&xtnData->nextProto, PR_FALSE); if (ex_type == ssl_app_layer_protocol_xtn && - ss->ssl3.nextProtoState != SSL_NEXT_PROTO_NEGOTIATED) { + xtnData->nextProtoState != SSL_NEXT_PROTO_NEGOTIATED) { /* The callback might say OK, but then it picks a default value - one * that was not listed. That's OK for NPN, but not ALPN. */ - (void)SSL3_SendAlert(ss, alert_fatal, no_application_protocol); + ssl3_ExtSendAlert(ss, alert_fatal, no_application_protocol); PORT_SetError(SSL_ERROR_NEXT_PROTOCOL_NO_PROTOCOL); return SECFailure; } - ss->xtnData.negotiated[ss->xtnData.numNegotiated++] = ex_type; - return SECITEM_CopyItem(NULL, &ss->ssl3.nextProto, &result); + xtnData->negotiated[xtnData->numNegotiated++] = ex_type; + return SECITEM_CopyItem(NULL, &xtnData->nextProto, &result); } /* handle an incoming ALPN extension at the server */ SECStatus -ssl3_ServerHandleAppProtoXtn(sslSocket *ss, PRUint16 ex_type, SECItem *data) +ssl3_ServerHandleAppProtoXtn(const sslSocket *ss, TLSExtensionData *xtnData, PRUint16 ex_type, SECItem *data) { int count; SECStatus rv; @@ -547,16 +549,16 @@ ssl3_ServerHandleAppProtoXtn(sslSocket *ss, PRUint16 ex_type, SECItem *data) * despite it being permitted by the spec. */ if (ss->firstHsDone || data->len == 0) { /* Clients MUST send a non-empty ALPN extension. */ - (void)SSL3_SendAlert(ss, alert_fatal, illegal_parameter); + ssl3_ExtSendAlert(ss, alert_fatal, illegal_parameter); PORT_SetError(SSL_ERROR_NEXT_PROTOCOL_DATA_INVALID); return SECFailure; } /* Unlike NPN, ALPN has extra redundant length information so that * the extension is the same in both ClientHello and ServerHello. */ - count = ssl3_ConsumeHandshakeNumber(ss, 2, &data->data, &data->len); + count = ssl3_ExtConsumeHandshakeNumber(ss, 2, &data->data, &data->len); if (count != data->len) { - (void)ssl3_DecodeError(ss); + ssl3_ExtDecodeError(ss); return SECFailure; } @@ -565,17 +567,17 @@ ssl3_ServerHandleAppProtoXtn(sslSocket *ss, PRUint16 ex_type, SECItem *data) return SECSuccess; } - rv = ssl3_SelectAppProtocol(ss, ex_type, data); + rv = ssl3_SelectAppProtocol(ss, xtnData, ex_type, data); if (rv != SECSuccess) { return rv; } /* prepare to send back a response, if we negotiated */ - if (ss->ssl3.nextProtoState == SSL_NEXT_PROTO_NEGOTIATED) { - rv = ssl3_RegisterServerHelloExtensionSender( - ss, ex_type, ssl3_ServerSendAppProtoXtn); + if (xtnData->nextProtoState == SSL_NEXT_PROTO_NEGOTIATED) { + rv = ssl3_RegisterExtensionSender( + ss, xtnData, ex_type, ssl3_ServerSendAppProtoXtn); if (rv != SECSuccess) { - (void)SSL3_SendAlert(ss, alert_fatal, internal_error); + ssl3_ExtSendAlert(ss, alert_fatal, internal_error); PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); return rv; } @@ -584,7 +586,7 @@ ssl3_ServerHandleAppProtoXtn(sslSocket *ss, PRUint16 ex_type, SECItem *data) } SECStatus -ssl3_ClientHandleNextProtoNegoXtn(sslSocket *ss, PRUint16 ex_type, +ssl3_ClientHandleNextProtoNegoXtn(const sslSocket *ss, TLSExtensionData *xtnData, PRUint16 ex_type, SECItem *data) { PORT_Assert(!ss->firstHsDone); @@ -596,7 +598,7 @@ ssl3_ClientHandleNextProtoNegoXtn(sslSocket *ss, PRUint16 ex_type, * we've negotiated NPN then we're required to send the NPN handshake * message. Thus, these two extensions cannot both be negotiated on the * same connection. */ - (void)SSL3_SendAlert(ss, alert_fatal, illegal_parameter); + ssl3_ExtSendAlert(ss, alert_fatal, illegal_parameter); PORT_SetError(SSL_ERROR_BAD_SERVER); return SECFailure; } @@ -607,16 +609,16 @@ ssl3_ClientHandleNextProtoNegoXtn(sslSocket *ss, PRUint16 ex_type, * we sent the ClientHello and now. */ if (!ss->nextProtoCallback) { PORT_Assert(0); - (void)SSL3_SendAlert(ss, alert_fatal, internal_error); + ssl3_ExtSendAlert(ss, alert_fatal, internal_error); PORT_SetError(SSL_ERROR_NEXT_PROTOCOL_NO_CALLBACK); return SECFailure; } - return ssl3_SelectAppProtocol(ss, ex_type, data); + return ssl3_SelectAppProtocol(ss, xtnData, ex_type, data); } SECStatus -ssl3_ClientHandleAppProtoXtn(sslSocket *ss, PRUint16 ex_type, SECItem *data) +ssl3_ClientHandleAppProtoXtn(const sslSocket *ss, TLSExtensionData *xtnData, PRUint16 ex_type, SECItem *data) { SECStatus rv; PRInt32 list_len; @@ -632,36 +634,36 @@ ssl3_ClientHandleAppProtoXtn(sslSocket *ss, PRUint16 ex_type, SECItem *data) * uint8 len; // where len >= 1 * uint8 protocol_name[len]; */ if (data->len < 4 || data->len > 2 + 1 + 255) { - (void)SSL3_SendAlert(ss, alert_fatal, decode_error); + ssl3_ExtSendAlert(ss, alert_fatal, decode_error); PORT_SetError(SSL_ERROR_NEXT_PROTOCOL_DATA_INVALID); return SECFailure; } - list_len = ssl3_ConsumeHandshakeNumber(ss, 2, &data->data, &data->len); + list_len = ssl3_ExtConsumeHandshakeNumber(ss, 2, &data->data, &data->len); /* The list has to be the entire extension. */ if (list_len != data->len) { - (void)SSL3_SendAlert(ss, alert_fatal, decode_error); + ssl3_ExtSendAlert(ss, alert_fatal, decode_error); PORT_SetError(SSL_ERROR_NEXT_PROTOCOL_DATA_INVALID); return SECFailure; } - rv = ssl3_ConsumeHandshakeVariable(ss, &protocol_name, 1, - &data->data, &data->len); + rv = ssl3_ExtConsumeHandshakeVariable(ss, &protocol_name, 1, + &data->data, &data->len); /* The list must have exactly one value. */ if (rv != SECSuccess || data->len != 0) { - (void)SSL3_SendAlert(ss, alert_fatal, decode_error); + ssl3_ExtSendAlert(ss, alert_fatal, decode_error); PORT_SetError(SSL_ERROR_NEXT_PROTOCOL_DATA_INVALID); return SECFailure; } - SECITEM_FreeItem(&ss->ssl3.nextProto, PR_FALSE); - ss->ssl3.nextProtoState = SSL_NEXT_PROTO_SELECTED; - ss->xtnData.negotiated[ss->xtnData.numNegotiated++] = ex_type; - return SECITEM_CopyItem(NULL, &ss->ssl3.nextProto, &protocol_name); + SECITEM_FreeItem(&xtnData->nextProto, PR_FALSE); + xtnData->nextProtoState = SSL_NEXT_PROTO_SELECTED; + xtnData->negotiated[xtnData->numNegotiated++] = ex_type; + return SECITEM_CopyItem(NULL, &xtnData->nextProto, &protocol_name); } PRInt32 -ssl3_ClientSendNextProtoNegoXtn(sslSocket *ss, PRBool append, +ssl3_ClientSendNextProtoNegoXtn(const sslSocket *ss, TLSExtensionData *xtnData, PRBool append, PRUint32 maxBytes) { PRInt32 extension_length; @@ -678,13 +680,13 @@ ssl3_ClientSendNextProtoNegoXtn(sslSocket *ss, PRBool append, } if (append) { SECStatus rv; - rv = ssl3_AppendHandshakeNumber(ss, ssl_next_proto_nego_xtn, 2); + rv = ssl3_ExtAppendHandshakeNumber(ss, ssl_next_proto_nego_xtn, 2); if (rv != SECSuccess) goto loser; - rv = ssl3_AppendHandshakeNumber(ss, 0, 2); + rv = ssl3_ExtAppendHandshakeNumber(ss, 0, 2); if (rv != SECSuccess) goto loser; - ss->xtnData.advertised[ss->xtnData.numAdvertised++] = + xtnData->advertised[xtnData->numAdvertised++] = ssl_next_proto_nego_xtn; } @@ -695,7 +697,7 @@ ssl3_ClientSendNextProtoNegoXtn(sslSocket *ss, PRBool append, } PRInt32 -ssl3_ClientSendAppProtoXtn(sslSocket *ss, PRBool append, PRUint32 maxBytes) +ssl3_ClientSendAppProtoXtn(const sslSocket *ss, TLSExtensionData *xtnData, PRBool append, PRUint32 maxBytes) { PRInt32 extension_length; unsigned char *alpn_protos = NULL; @@ -736,21 +738,21 @@ ssl3_ClientSendAppProtoXtn(sslSocket *ss, PRBool append, PRUint32 maxBytes) } } - rv = ssl3_AppendHandshakeNumber(ss, ssl_app_layer_protocol_xtn, 2); + rv = ssl3_ExtAppendHandshakeNumber(ss, ssl_app_layer_protocol_xtn, 2); if (rv != SECSuccess) { goto loser; } - rv = ssl3_AppendHandshakeNumber(ss, extension_length - 4, 2); + rv = ssl3_ExtAppendHandshakeNumber(ss, extension_length - 4, 2); if (rv != SECSuccess) { goto loser; } - rv = ssl3_AppendHandshakeVariable(ss, alpn_protos, len, 2); + rv = ssl3_ExtAppendHandshakeVariable(ss, alpn_protos, len, 2); PORT_Free(alpn_protos); alpn_protos = NULL; if (rv != SECSuccess) { goto loser; } - ss->xtnData.advertised[ss->xtnData.numAdvertised++] = + xtnData->advertised[xtnData->numAdvertised++] = ssl_app_layer_protocol_xtn; } @@ -764,40 +766,40 @@ ssl3_ClientSendAppProtoXtn(sslSocket *ss, PRBool append, PRUint32 maxBytes) } PRInt32 -ssl3_ServerSendAppProtoXtn(sslSocket *ss, PRBool append, PRUint32 maxBytes) +ssl3_ServerSendAppProtoXtn(const sslSocket *ss, TLSExtensionData *xtnData, PRBool append, PRUint32 maxBytes) { PRInt32 extension_length; /* we're in over our heads if any of these fail */ PORT_Assert(ss->opt.enableALPN); - PORT_Assert(ss->ssl3.nextProto.data); - PORT_Assert(ss->ssl3.nextProto.len > 0); - PORT_Assert(ss->ssl3.nextProtoState == SSL_NEXT_PROTO_NEGOTIATED); + PORT_Assert(xtnData->nextProto.data); + PORT_Assert(xtnData->nextProto.len > 0); + PORT_Assert(xtnData->nextProtoState == SSL_NEXT_PROTO_NEGOTIATED); PORT_Assert(!ss->firstHsDone); extension_length = 2 /* extension type */ + 2 /* extension length */ + 2 /* protocol name list */ + 1 /* name length */ + - ss->ssl3.nextProto.len; + xtnData->nextProto.len; if (maxBytes < (PRUint32)extension_length) { return 0; } if (append) { SECStatus rv; - rv = ssl3_AppendHandshakeNumber(ss, ssl_app_layer_protocol_xtn, 2); + rv = ssl3_ExtAppendHandshakeNumber(ss, ssl_app_layer_protocol_xtn, 2); if (rv != SECSuccess) { return -1; } - rv = ssl3_AppendHandshakeNumber(ss, extension_length - 4, 2); + rv = ssl3_ExtAppendHandshakeNumber(ss, extension_length - 4, 2); if (rv != SECSuccess) { return -1; } - rv = ssl3_AppendHandshakeNumber(ss, ss->ssl3.nextProto.len + 1, 2); + rv = ssl3_ExtAppendHandshakeNumber(ss, xtnData->nextProto.len + 1, 2); if (rv != SECSuccess) { return -1; } - rv = ssl3_AppendHandshakeVariable(ss, ss->ssl3.nextProto.data, - ss->ssl3.nextProto.len, 1); + rv = ssl3_ExtAppendHandshakeVariable(ss, xtnData->nextProto.data, + xtnData->nextProto.len, 1); if (rv != SECSuccess) { return -1; } @@ -807,7 +809,7 @@ ssl3_ServerSendAppProtoXtn(sslSocket *ss, PRBool append, PRUint32 maxBytes) } SECStatus -ssl3_ServerHandleStatusRequestXtn(sslSocket *ss, PRUint16 ex_type, +ssl3_ServerHandleStatusRequestXtn(const sslSocket *ss, TLSExtensionData *xtnData, PRUint16 ex_type, SECItem *data) { ssl3HelloExtensionSenderFunc sender; @@ -815,19 +817,20 @@ ssl3_ServerHandleStatusRequestXtn(sslSocket *ss, PRUint16 ex_type, PORT_Assert(ss->sec.isServer); /* remember that we got this extension. */ - ss->xtnData.negotiated[ss->xtnData.numNegotiated++] = ex_type; + xtnData->negotiated[xtnData->numNegotiated++] = ex_type; if (ss->version >= SSL_LIBRARY_VERSION_TLS_1_3) { sender = tls13_ServerSendStatusRequestXtn; } else { sender = ssl3_ServerSendStatusRequestXtn; } - return ssl3_RegisterServerHelloExtensionSender(ss, ex_type, sender); + return ssl3_RegisterExtensionSender(ss, xtnData, ex_type, sender); } PRInt32 ssl3_ServerSendStatusRequestXtn( - sslSocket *ss, + const sslSocket *ss, + TLSExtensionData *xtnData, PRBool append, PRUint32 maxBytes) { @@ -846,11 +849,11 @@ ssl3_ServerSendStatusRequestXtn( } if (append) { /* extension_type */ - rv = ssl3_AppendHandshakeNumber(ss, ssl_cert_status_xtn, 2); + rv = ssl3_ExtAppendHandshakeNumber(ss, ssl_cert_status_xtn, 2); if (rv != SECSuccess) return -1; /* length of extension_data */ - rv = ssl3_AppendHandshakeNumber(ss, 0, 2); + rv = ssl3_ExtAppendHandshakeNumber(ss, 0, 2); if (rv != SECSuccess) return -1; /* The certificate status data is sent in ssl3_SendCertificateStatus. */ @@ -862,7 +865,7 @@ ssl3_ServerSendStatusRequestXtn( /* ssl3_ClientSendStatusRequestXtn builds the status_request extension on the * client side. See RFC 6066 section 8. */ PRInt32 -ssl3_ClientSendStatusRequestXtn(sslSocket *ss, PRBool append, +ssl3_ClientSendStatusRequestXtn(const sslSocket *ss, TLSExtensionData *xtnData, PRBool append, PRUint32 maxBytes) { PRInt32 extension_length; @@ -884,55 +887,54 @@ ssl3_ClientSendStatusRequestXtn(sslSocket *ss, PRBool append, } if (append) { SECStatus rv; - TLSExtensionData *xtnData; /* extension_type */ - rv = ssl3_AppendHandshakeNumber(ss, ssl_cert_status_xtn, 2); + rv = ssl3_ExtAppendHandshakeNumber(ss, ssl_cert_status_xtn, 2); if (rv != SECSuccess) return -1; - rv = ssl3_AppendHandshakeNumber(ss, extension_length - 4, 2); + rv = ssl3_ExtAppendHandshakeNumber(ss, extension_length - 4, 2); if (rv != SECSuccess) return -1; - rv = ssl3_AppendHandshakeNumber(ss, 1 /* status_type ocsp */, 1); + rv = ssl3_ExtAppendHandshakeNumber(ss, 1 /* status_type ocsp */, 1); if (rv != SECSuccess) return -1; /* A zero length responder_id_list means that the responders are * implicitly known to the server. */ - rv = ssl3_AppendHandshakeNumber(ss, 0, 2); + rv = ssl3_ExtAppendHandshakeNumber(ss, 0, 2); if (rv != SECSuccess) return -1; /* A zero length request_extensions means that there are no extensions. * Specifically, we don't set the id-pkix-ocsp-nonce extension. This * means that the server can replay a cached OCSP response to us. */ - rv = ssl3_AppendHandshakeNumber(ss, 0, 2); + rv = ssl3_ExtAppendHandshakeNumber(ss, 0, 2); if (rv != SECSuccess) return -1; - xtnData = &ss->xtnData; xtnData->advertised[xtnData->numAdvertised++] = ssl_cert_status_xtn; } return extension_length; } SECStatus -ssl3_ClientHandleStatusRequestXtn(sslSocket *ss, PRUint16 ex_type, +ssl3_ClientHandleStatusRequestXtn(const sslSocket *ss, TLSExtensionData *xtnData, PRUint16 ex_type, SECItem *data) { /* In TLS 1.3, the extension carries the OCSP response. */ if (ss->version >= SSL_LIBRARY_VERSION_TLS_1_3) { SECStatus rv; - rv = ssl_ReadCertificateStatus(ss, data->data, data->len); + rv = ssl_ReadCertificateStatus(CONST_CAST(sslSocket, ss), + data->data, data->len); if (rv != SECSuccess) { return SECFailure; /* code already set */ } } else if (data->len != 0) { - (void)SSL3_SendAlert(ss, alert_fatal, illegal_parameter); + ssl3_ExtSendAlert(ss, alert_fatal, illegal_parameter); PORT_SetError(SSL_ERROR_RX_MALFORMED_SERVER_HELLO); return SECFailure; } /* Keep track of negotiated extensions. */ - ss->xtnData.negotiated[ss->xtnData.numNegotiated++] = ex_type; + xtnData->negotiated[xtnData->numNegotiated++] = ex_type; return SECSuccess; } @@ -1037,9 +1039,9 @@ ssl3_EncodeSessionTicket(sslSocket *ss, srvNameLen = 2 + srvName->len; /* len bytes + name len */ } - if (ss->ssl3.nextProtoState != SSL_NEXT_PROTO_NO_SUPPORT && - ss->ssl3.nextProto.data) { - alpnSelection = ss->ssl3.nextProto; + if (ss->xtnData.nextProtoState != SSL_NEXT_PROTO_NO_SUPPORT && + ss->xtnData.nextProto.data) { + alpnSelection = ss->xtnData.nextProto; } ciphertext_length = @@ -1324,7 +1326,7 @@ ssl3_EncodeSessionTicket(sslSocket *ss, * message is expected during the handshake. */ SECStatus -ssl3_ClientHandleSessionTicketXtn(sslSocket *ss, PRUint16 ex_type, +ssl3_ClientHandleSessionTicketXtn(const sslSocket *ss, TLSExtensionData *xtnData, PRUint16 ex_type, SECItem *data) { if (data->len != 0) { @@ -1332,7 +1334,7 @@ ssl3_ClientHandleSessionTicketXtn(sslSocket *ss, PRUint16 ex_type, } /* Keep track of negotiated extensions. */ - ss->xtnData.negotiated[ss->xtnData.numNegotiated++] = ex_type; + xtnData->negotiated[xtnData->numNegotiated++] = ex_type; return SECSuccess; } @@ -1497,51 +1499,51 @@ ssl3_ProcessSessionTicketCommon(sslSocket *ss, SECItem *data) } /* Read ticket_version and reject if the version is wrong */ - temp = ssl3_ConsumeHandshakeNumber(ss, 2, &buffer, &buffer_len); + temp = ssl3_ExtConsumeHandshakeNumber(ss, 2, &buffer, &buffer_len); if (temp != TLS_EX_SESS_TICKET_VERSION) goto no_ticket; parsed_session_ticket->ticket_version = (SSL3ProtocolVersion)temp; /* Read SSLVersion. */ - temp = ssl3_ConsumeHandshakeNumber(ss, 2, &buffer, &buffer_len); + temp = ssl3_ExtConsumeHandshakeNumber(ss, 2, &buffer, &buffer_len); if (temp < 0) goto no_ticket; parsed_session_ticket->ssl_version = (SSL3ProtocolVersion)temp; /* Read cipher_suite. */ - temp = ssl3_ConsumeHandshakeNumber(ss, 2, &buffer, &buffer_len); + temp = ssl3_ExtConsumeHandshakeNumber(ss, 2, &buffer, &buffer_len); if (temp < 0) goto no_ticket; parsed_session_ticket->cipher_suite = (ssl3CipherSuite)temp; /* Read compression_method. */ - temp = ssl3_ConsumeHandshakeNumber(ss, 1, &buffer, &buffer_len); + temp = ssl3_ExtConsumeHandshakeNumber(ss, 1, &buffer, &buffer_len); if (temp < 0) goto no_ticket; parsed_session_ticket->compression_method = (SSLCompressionMethod)temp; /* Read cipher spec parameters. */ - temp = ssl3_ConsumeHandshakeNumber(ss, 1, &buffer, &buffer_len); + temp = ssl3_ExtConsumeHandshakeNumber(ss, 1, &buffer, &buffer_len); if (temp < 0) goto no_ticket; parsed_session_ticket->authType = (SSLAuthType)temp; - temp = ssl3_ConsumeHandshakeNumber(ss, 4, &buffer, &buffer_len); + temp = ssl3_ExtConsumeHandshakeNumber(ss, 4, &buffer, &buffer_len); if (temp < 0) goto no_ticket; parsed_session_ticket->authKeyBits = (PRUint32)temp; - temp = ssl3_ConsumeHandshakeNumber(ss, 1, &buffer, &buffer_len); + temp = ssl3_ExtConsumeHandshakeNumber(ss, 1, &buffer, &buffer_len); if (temp < 0) goto no_ticket; parsed_session_ticket->keaType = (SSLKEAType)temp; - temp = ssl3_ConsumeHandshakeNumber(ss, 4, &buffer, &buffer_len); + temp = ssl3_ExtConsumeHandshakeNumber(ss, 4, &buffer, &buffer_len); if (temp < 0) goto no_ticket; parsed_session_ticket->keaKeyBits = (PRUint32)temp; /* Read certificate slot */ parsed_session_ticket->certType.authType = parsed_session_ticket->authType; - temp = ssl3_ConsumeHandshakeNumber(ss, 1, &buffer, &buffer_len); + temp = ssl3_ExtConsumeHandshakeNumber(ss, 1, &buffer, &buffer_len); if (temp < 0) goto no_ticket; switch (parsed_session_ticket->authType) { @@ -1560,17 +1562,17 @@ ssl3_ProcessSessionTicketCommon(sslSocket *ss, SECItem *data) } /* Read wrapped master_secret. */ - temp = ssl3_ConsumeHandshakeNumber(ss, 1, &buffer, &buffer_len); + temp = ssl3_ExtConsumeHandshakeNumber(ss, 1, &buffer, &buffer_len); if (temp < 0) goto no_ticket; parsed_session_ticket->ms_is_wrapped = (PRBool)temp; - temp = ssl3_ConsumeHandshakeNumber(ss, 4, &buffer, &buffer_len); + temp = ssl3_ExtConsumeHandshakeNumber(ss, 4, &buffer, &buffer_len); if (temp < 0) goto no_ticket; parsed_session_ticket->msWrapMech = (CK_MECHANISM_TYPE)temp; - temp = ssl3_ConsumeHandshakeNumber(ss, 2, &buffer, &buffer_len); + temp = ssl3_ExtConsumeHandshakeNumber(ss, 2, &buffer, &buffer_len); if (temp < 0) goto no_ticket; parsed_session_ticket->ms_length = (PRUint16)temp; @@ -1588,7 +1590,7 @@ ssl3_ProcessSessionTicketCommon(sslSocket *ss, SECItem *data) buffer_len -= parsed_session_ticket->ms_length; /* Read client_identity */ - temp = ssl3_ConsumeHandshakeNumber(ss, 1, &buffer, &buffer_len); + temp = ssl3_ExtConsumeHandshakeNumber(ss, 1, &buffer, &buffer_len); if (temp < 0) goto no_ticket; parsed_session_ticket->client_identity.client_auth_type = @@ -1597,8 +1599,8 @@ ssl3_ProcessSessionTicketCommon(sslSocket *ss, SECItem *data) case CLIENT_AUTH_ANONYMOUS: break; case CLIENT_AUTH_CERTIFICATE: - rv = ssl3_ConsumeHandshakeVariable(ss, &cert_item, 3, - &buffer, &buffer_len); + rv = ssl3_ExtConsumeHandshakeVariable(ss, &cert_item, 3, + &buffer, &buffer_len); if (rv != SECSuccess) goto no_ticket; rv = SECITEM_CopyItem(NULL, &parsed_session_ticket->peer_cert, @@ -1610,18 +1612,18 @@ ssl3_ProcessSessionTicketCommon(sslSocket *ss, SECItem *data) goto no_ticket; } /* Read timestamp. */ - temp = ssl3_ConsumeHandshakeNumber(ss, 4, &buffer, &buffer_len); + temp = ssl3_ExtConsumeHandshakeNumber(ss, 4, &buffer, &buffer_len); if (temp < 0) goto no_ticket; parsed_session_ticket->timestamp = (PRUint32)temp; /* Read server name */ nameType = - ssl3_ConsumeHandshakeNumber(ss, 1, &buffer, &buffer_len); + ssl3_ExtConsumeHandshakeNumber(ss, 1, &buffer, &buffer_len); if (nameType != TLS_STE_NO_SERVER_NAME) { SECItem name_item; - rv = ssl3_ConsumeHandshakeVariable(ss, &name_item, 2, &buffer, - &buffer_len); + rv = ssl3_ExtConsumeHandshakeVariable(ss, &name_item, 2, &buffer, + &buffer_len); if (rv != SECSuccess) goto no_ticket; rv = SECITEM_CopyItem(NULL, &parsed_session_ticket->srvName, @@ -1632,19 +1634,19 @@ ssl3_ProcessSessionTicketCommon(sslSocket *ss, SECItem *data) } /* Read extendedMasterSecretUsed */ - temp = ssl3_ConsumeHandshakeNumber(ss, 1, &buffer, &buffer_len); + temp = ssl3_ExtConsumeHandshakeNumber(ss, 1, &buffer, &buffer_len); if (temp < 0) goto no_ticket; PORT_Assert(temp == PR_TRUE || temp == PR_FALSE); parsed_session_ticket->extendedMasterSecretUsed = (PRBool)temp; - rv = ssl3_ConsumeHandshake(ss, &parsed_session_ticket->flags, 4, - &buffer, &buffer_len); + rv = ssl3_ExtConsumeHandshake(ss, &parsed_session_ticket->flags, 4, + &buffer, &buffer_len); if (rv != SECSuccess) goto no_ticket; parsed_session_ticket->flags = PR_ntohl(parsed_session_ticket->flags); - rv = ssl3_ConsumeHandshakeVariable(ss, &alpn_item, 1, &buffer, &buffer_len); + rv = ssl3_ExtConsumeHandshakeVariable(ss, &alpn_item, 1, &buffer, &buffer_len); if (rv != SECSuccess) goto no_ticket; if (alpn_item.len != 0) { @@ -1767,7 +1769,7 @@ ssl3_ProcessSessionTicketCommon(sslSocket *ss, SECItem *data) } SECStatus -ssl3_ServerHandleSessionTicketXtn(sslSocket *ss, PRUint16 ex_type, +ssl3_ServerHandleSessionTicketXtn(const sslSocket *ss, TLSExtensionData *xtnData, PRUint16 ex_type, SECItem *data) { @@ -1782,18 +1784,18 @@ ssl3_ServerHandleSessionTicketXtn(sslSocket *ss, PRUint16 ex_type, } /* Keep track of negotiated extensions. */ - ss->xtnData.negotiated[ss->xtnData.numNegotiated++] = ex_type; + xtnData->negotiated[xtnData->numNegotiated++] = ex_type; /* Parse the received ticket sent in by the client. We are * lenient about some parse errors, falling back to a fullshake * instead of terminating the current connection. */ if (data->len == 0) { - ss->xtnData.emptySessionTicket = PR_TRUE; + xtnData->emptySessionTicket = PR_TRUE; return SECSuccess; } - return ssl3_ProcessSessionTicketCommon(ss, data); + return ssl3_ProcessSessionTicketCommon(CONST_CAST(sslSocket, ss), data); } /* @@ -1822,7 +1824,8 @@ ssl3_ConsumeFromItem(SECItem *item, unsigned char **buf, PRUint32 bytes) */ PRInt32 ssl3_SendRenegotiationInfoXtn( - sslSocket *ss, + const sslSocket *ss, + TLSExtensionData *xtnData, PRBool append, PRUint32 maxBytes) { @@ -1846,20 +1849,19 @@ ssl3_SendRenegotiationInfoXtn( if (append) { SECStatus rv; /* extension_type */ - rv = ssl3_AppendHandshakeNumber(ss, ssl_renegotiation_info_xtn, 2); + rv = ssl3_ExtAppendHandshakeNumber(ss, ssl_renegotiation_info_xtn, 2); if (rv != SECSuccess) return -1; /* length of extension_data */ - rv = ssl3_AppendHandshakeNumber(ss, len + 1, 2); + rv = ssl3_ExtAppendHandshakeNumber(ss, len + 1, 2); if (rv != SECSuccess) return -1; /* verify_Data from previous Finished message(s) */ - rv = ssl3_AppendHandshakeVariable(ss, - ss->ssl3.hs.finishedMsgs.data, len, 1); + rv = ssl3_ExtAppendHandshakeVariable(ss, + ss->ssl3.hs.finishedMsgs.data, len, 1); if (rv != SECSuccess) return -1; if (!ss->sec.isServer) { - TLSExtensionData *xtnData = &ss->xtnData; xtnData->advertised[xtnData->numAdvertised++] = ssl_renegotiation_info_xtn; } @@ -1869,7 +1871,7 @@ ssl3_SendRenegotiationInfoXtn( /* This function runs in both the client and server. */ SECStatus -ssl3_HandleRenegotiationInfoXtn(sslSocket *ss, PRUint16 ex_type, SECItem *data) +ssl3_HandleRenegotiationInfoXtn(const sslSocket *ss, TLSExtensionData *xtnData, PRUint16 ex_type, SECItem *data) { SECStatus rv = SECSuccess; PRUint32 len = 0; @@ -1879,28 +1881,29 @@ ssl3_HandleRenegotiationInfoXtn(sslSocket *ss, PRUint16 ex_type, SECItem *data) : ss->ssl3.hs.finishedBytes * 2; } if (data->len != 1 + len || data->data[0] != len) { - (void)ssl3_DecodeError(ss); + ssl3_ExtDecodeError(ss); return SECFailure; } if (len && NSS_SecureMemcmp(ss->ssl3.hs.finishedMsgs.data, data->data + 1, len)) { - (void)SSL3_SendAlert(ss, alert_fatal, handshake_failure); + ssl3_ExtSendAlert(ss, alert_fatal, handshake_failure); PORT_SetError(SSL_ERROR_BAD_HANDSHAKE_HASH_VALUE); return SECFailure; } /* remember that we got this extension and it was correct. */ - ss->peerRequestedProtection = 1; - ss->xtnData.negotiated[ss->xtnData.numNegotiated++] = ex_type; + CONST_CAST(sslSocket, ss) + ->peerRequestedProtection = 1; + xtnData->negotiated[xtnData->numNegotiated++] = ex_type; if (ss->sec.isServer) { /* prepare to send back the appropriate response */ - rv = ssl3_RegisterServerHelloExtensionSender(ss, ex_type, - ssl3_SendRenegotiationInfoXtn); + rv = ssl3_RegisterExtensionSender(ss, xtnData, ex_type, + ssl3_SendRenegotiationInfoXtn); } return rv; } PRInt32 -ssl3_ClientSendUseSRTPXtn(sslSocket *ss, PRBool append, PRUint32 maxBytes) +ssl3_ClientSendUseSRTPXtn(const sslSocket *ss, TLSExtensionData *xtnData, PRBool append, PRUint32 maxBytes) { PRUint32 ext_data_len; PRInt16 i; @@ -1916,31 +1919,31 @@ ssl3_ClientSendUseSRTPXtn(sslSocket *ss, PRBool append, PRUint32 maxBytes) if (append && maxBytes >= 4 + ext_data_len) { /* Extension type */ - rv = ssl3_AppendHandshakeNumber(ss, ssl_use_srtp_xtn, 2); + rv = ssl3_ExtAppendHandshakeNumber(ss, ssl_use_srtp_xtn, 2); if (rv != SECSuccess) return -1; /* Length of extension data */ - rv = ssl3_AppendHandshakeNumber(ss, ext_data_len, 2); + rv = ssl3_ExtAppendHandshakeNumber(ss, ext_data_len, 2); if (rv != SECSuccess) return -1; /* Length of the SRTP cipher list */ - rv = ssl3_AppendHandshakeNumber(ss, - 2 * ss->ssl3.dtlsSRTPCipherCount, - 2); + rv = ssl3_ExtAppendHandshakeNumber(ss, + 2 * ss->ssl3.dtlsSRTPCipherCount, + 2); if (rv != SECSuccess) return -1; /* The SRTP ciphers */ for (i = 0; i < ss->ssl3.dtlsSRTPCipherCount; i++) { - rv = ssl3_AppendHandshakeNumber(ss, - ss->ssl3.dtlsSRTPCiphers[i], - 2); + rv = ssl3_ExtAppendHandshakeNumber(ss, + ss->ssl3.dtlsSRTPCiphers[i], + 2); if (rv != SECSuccess) return -1; } /* Empty MKI value */ - ssl3_AppendHandshakeVariable(ss, NULL, 0, 1); + ssl3_ExtAppendHandshakeVariable(ss, NULL, 0, 1); - ss->xtnData.advertised[ss->xtnData.numAdvertised++] = + xtnData->advertised[xtnData->numAdvertised++] = ssl_use_srtp_xtn; } @@ -1948,7 +1951,7 @@ ssl3_ClientSendUseSRTPXtn(sslSocket *ss, PRBool append, PRUint32 maxBytes) } PRInt32 -ssl3_ServerSendUseSRTPXtn(sslSocket *ss, PRBool append, PRUint32 maxBytes) +ssl3_ServerSendUseSRTPXtn(const sslSocket *ss, TLSExtensionData *xtnData, PRBool append, PRUint32 maxBytes) { SECStatus rv; @@ -1958,29 +1961,29 @@ ssl3_ServerSendUseSRTPXtn(sslSocket *ss, PRBool append, PRUint32 maxBytes) } /* Extension type */ - rv = ssl3_AppendHandshakeNumber(ss, ssl_use_srtp_xtn, 2); + rv = ssl3_ExtAppendHandshakeNumber(ss, ssl_use_srtp_xtn, 2); if (rv != SECSuccess) return -1; /* Length of extension data */ - rv = ssl3_AppendHandshakeNumber(ss, 5, 2); + rv = ssl3_ExtAppendHandshakeNumber(ss, 5, 2); if (rv != SECSuccess) return -1; /* Length of the SRTP cipher list */ - rv = ssl3_AppendHandshakeNumber(ss, 2, 2); + rv = ssl3_ExtAppendHandshakeNumber(ss, 2, 2); if (rv != SECSuccess) return -1; /* The selected cipher */ - rv = ssl3_AppendHandshakeNumber(ss, ss->ssl3.dtlsSRTPCipherSuite, 2); + rv = ssl3_ExtAppendHandshakeNumber(ss, xtnData->dtlsSRTPCipherSuite, 2); if (rv != SECSuccess) return -1; /* Empty MKI value */ - ssl3_AppendHandshakeVariable(ss, NULL, 0, 1); + ssl3_ExtAppendHandshakeVariable(ss, NULL, 0, 1); return 9; } SECStatus -ssl3_ClientHandleUseSRTPXtn(sslSocket *ss, PRUint16 ex_type, SECItem *data) +ssl3_ClientHandleUseSRTPXtn(const sslSocket *ss, TLSExtensionData *xtnData, PRUint16 ex_type, SECItem *data) { SECStatus rv; SECItem ciphers = { siBuffer, NULL, 0 }; @@ -1990,19 +1993,19 @@ ssl3_ClientHandleUseSRTPXtn(sslSocket *ss, PRUint16 ex_type, SECItem *data) SECItem litem; if (!data->data || !data->len) { - (void)ssl3_DecodeError(ss); + ssl3_ExtDecodeError(ss); return SECFailure; } /* Get the cipher list */ - rv = ssl3_ConsumeHandshakeVariable(ss, &ciphers, 2, - &data->data, &data->len); + rv = ssl3_ExtConsumeHandshakeVariable(ss, &ciphers, 2, + &data->data, &data->len); if (rv != SECSuccess) { return SECFailure; /* fatal alert already sent */ } /* Now check that the server has picked just 1 (i.e., len = 2) */ if (ciphers.len != 2) { - (void)ssl3_DecodeError(ss); + ssl3_ExtDecodeError(ss); return SECFailure; } @@ -2018,39 +2021,39 @@ ssl3_ClientHandleUseSRTPXtn(sslSocket *ss, PRUint16 ex_type, SECItem *data) } if (!found) { - (void)SSL3_SendAlert(ss, alert_fatal, illegal_parameter); + ssl3_ExtSendAlert(ss, alert_fatal, illegal_parameter); PORT_SetError(SSL_ERROR_RX_MALFORMED_SERVER_HELLO); return SECFailure; } /* Get the srtp_mki value */ - rv = ssl3_ConsumeHandshakeVariable(ss, &litem, 1, - &data->data, &data->len); + rv = ssl3_ExtConsumeHandshakeVariable(ss, &litem, 1, + &data->data, &data->len); if (rv != SECSuccess) { return SECFailure; /* alert already sent */ } /* We didn't offer an MKI, so this must be 0 length */ if (litem.len != 0) { - (void)SSL3_SendAlert(ss, alert_fatal, illegal_parameter); + ssl3_ExtSendAlert(ss, alert_fatal, illegal_parameter); PORT_SetError(SSL_ERROR_RX_MALFORMED_SERVER_HELLO); return SECFailure; } /* extra trailing bytes */ if (data->len != 0) { - (void)ssl3_DecodeError(ss); + ssl3_ExtDecodeError(ss); return SECFailure; } /* OK, this looks fine. */ - ss->xtnData.negotiated[ss->xtnData.numNegotiated++] = ssl_use_srtp_xtn; - ss->ssl3.dtlsSRTPCipherSuite = cipher; + xtnData->negotiated[xtnData->numNegotiated++] = ssl_use_srtp_xtn; + xtnData->dtlsSRTPCipherSuite = cipher; return SECSuccess; } SECStatus -ssl3_ServerHandleUseSRTPXtn(sslSocket *ss, PRUint16 ex_type, SECItem *data) +ssl3_ServerHandleUseSRTPXtn(const sslSocket *ss, TLSExtensionData *xtnData, PRUint16 ex_type, SECItem *data) { SECStatus rv; SECItem ciphers = { siBuffer, NULL, 0 }; @@ -2067,19 +2070,19 @@ ssl3_ServerHandleUseSRTPXtn(sslSocket *ss, PRUint16 ex_type, SECItem *data) } if (!data->data || data->len < 5) { - (void)ssl3_DecodeError(ss); + ssl3_ExtDecodeError(ss); return SECFailure; } /* Get the cipher list */ - rv = ssl3_ConsumeHandshakeVariable(ss, &ciphers, 2, - &data->data, &data->len); + rv = ssl3_ExtConsumeHandshakeVariable(ss, &ciphers, 2, + &data->data, &data->len); if (rv != SECSuccess) { return SECFailure; /* alert already sent */ } /* Check that the list is even length */ if (ciphers.len % 2) { - (void)ssl3_DecodeError(ss); + ssl3_ExtDecodeError(ss); return SECFailure; } @@ -2096,13 +2099,13 @@ ssl3_ServerHandleUseSRTPXtn(sslSocket *ss, PRUint16 ex_type, SECItem *data) } /* Get the srtp_mki value */ - rv = ssl3_ConsumeHandshakeVariable(ss, &litem, 1, &data->data, &data->len); + rv = ssl3_ExtConsumeHandshakeVariable(ss, &litem, 1, &data->data, &data->len); if (rv != SECSuccess) { return SECFailure; } if (data->len != 0) { - (void)ssl3_DecodeError(ss); /* trailing bytes */ + ssl3_ExtDecodeError(ss); /* trailing bytes */ return SECFailure; } @@ -2113,18 +2116,19 @@ ssl3_ServerHandleUseSRTPXtn(sslSocket *ss, PRUint16 ex_type, SECItem *data) } /* OK, we have a valid cipher and we've selected it */ - ss->ssl3.dtlsSRTPCipherSuite = cipher; - ss->xtnData.negotiated[ss->xtnData.numNegotiated++] = ssl_use_srtp_xtn; + xtnData->dtlsSRTPCipherSuite = cipher; + xtnData->negotiated[xtnData->numNegotiated++] = ssl_use_srtp_xtn; - return ssl3_RegisterServerHelloExtensionSender(ss, ssl_use_srtp_xtn, - ssl3_ServerSendUseSRTPXtn); + return ssl3_RegisterExtensionSender(ss, xtnData, + ssl_use_srtp_xtn, + 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 */ SECStatus -ssl3_ServerHandleSigAlgsXtn(sslSocket *ss, PRUint16 ex_type, SECItem *data) +ssl3_ServerHandleSigAlgsXtn(const sslSocket *ss, TLSExtensionData *xtnData, PRUint16 ex_type, SECItem *data) { SECStatus rv; @@ -2133,13 +2137,13 @@ ssl3_ServerHandleSigAlgsXtn(sslSocket *ss, PRUint16 ex_type, SECItem *data) return SECSuccess; } - if (ss->ssl3.hs.clientSigSchemes) { - PORT_Free(ss->ssl3.hs.clientSigSchemes); - ss->ssl3.hs.clientSigSchemes = NULL; + if (xtnData->clientSigSchemes) { + PORT_Free(xtnData->clientSigSchemes); + xtnData->clientSigSchemes = NULL; } rv = ssl_ParseSignatureSchemes(ss, NULL, - &ss->ssl3.hs.clientSigSchemes, - &ss->ssl3.hs.numClientSigScheme, + &xtnData->clientSigSchemes, + &xtnData->numClientSigScheme, &data->data, &data->len); if (rv != SECSuccess) { PORT_SetError(SSL_ERROR_RX_MALFORMED_CLIENT_HELLO); @@ -2147,20 +2151,20 @@ ssl3_ServerHandleSigAlgsXtn(sslSocket *ss, PRUint16 ex_type, SECItem *data) } /* Check for trailing data. */ if (data->len != 0) { - (void)SSL3_SendAlert(ss, alert_fatal, decode_error); + ssl3_ExtSendAlert(ss, alert_fatal, decode_error); PORT_SetError(SSL_ERROR_RX_MALFORMED_CLIENT_HELLO); return SECFailure; } /* Keep track of negotiated extensions. */ - ss->xtnData.negotiated[ss->xtnData.numNegotiated++] = ex_type; + xtnData->negotiated[xtnData->numNegotiated++] = ex_type; return SECSuccess; } /* ssl3_ClientSendSigAlgsXtn sends the signature_algorithm extension for TLS * 1.2 ClientHellos. */ PRInt32 -ssl3_ClientSendSigAlgsXtn(sslSocket *ss, PRBool append, PRUint32 maxBytes) +ssl3_ClientSendSigAlgsXtn(const sslSocket *ss, TLSExtensionData *xtnData, PRBool append, PRUint32 maxBytes) { PRInt32 extension_length; PRUint8 buf[MAX_SIGNATURE_SCHEMES * 2]; @@ -2189,21 +2193,21 @@ ssl3_ClientSendSigAlgsXtn(sslSocket *ss, PRBool append, PRUint32 maxBytes) if (append) { SECStatus rv; - rv = ssl3_AppendHandshakeNumber(ss, ssl_signature_algorithms_xtn, 2); + rv = ssl3_ExtAppendHandshakeNumber(ss, ssl_signature_algorithms_xtn, 2); if (rv != SECSuccess) { return -1; } - rv = ssl3_AppendHandshakeNumber(ss, len + 2, 2); + rv = ssl3_ExtAppendHandshakeNumber(ss, len + 2, 2); if (rv != SECSuccess) { return -1; } - rv = ssl3_AppendHandshakeVariable(ss, buf, len, 2); + rv = ssl3_ExtAppendHandshakeVariable(ss, buf, len, 2); if (rv != SECSuccess) { return -1; } - ss->xtnData.advertised[ss->xtnData.numAdvertised++] = + xtnData->advertised[xtnData->numAdvertised++] = ssl_signature_algorithms_xtn; } @@ -2257,16 +2261,16 @@ ssl3_AppendPaddingExtension(sslSocket *ss, unsigned int extensionLen, return -1; } - if (SECSuccess != ssl3_AppendHandshakeNumber(ss, ssl_padding_xtn, 2)) + if (SECSuccess != ssl3_ExtAppendHandshakeNumber(ss, ssl_padding_xtn, 2)) return -1; - if (SECSuccess != ssl3_AppendHandshakeVariable(ss, padding, paddingLen, 2)) + if (SECSuccess != ssl3_ExtAppendHandshakeVariable(ss, padding, paddingLen, 2)) return -1; return extensionLen; } PRInt32 -ssl3_SendExtendedMasterSecretXtn(sslSocket *ss, PRBool append, +ssl3_SendExtendedMasterSecretXtn(const sslSocket *ss, TLSExtensionData *xtnData, PRBool append, PRUint32 maxBytes) { PRInt32 extension_length; @@ -2286,13 +2290,13 @@ ssl3_SendExtendedMasterSecretXtn(sslSocket *ss, PRBool append, if (append) { SECStatus rv; - rv = ssl3_AppendHandshakeNumber(ss, ssl_extended_master_secret_xtn, 2); + rv = ssl3_ExtAppendHandshakeNumber(ss, ssl_extended_master_secret_xtn, 2); if (rv != SECSuccess) goto loser; - rv = ssl3_AppendHandshakeNumber(ss, 0, 2); + rv = ssl3_ExtAppendHandshakeNumber(ss, 0, 2); if (rv != SECSuccess) goto loser; - ss->xtnData.advertised[ss->xtnData.numAdvertised++] = + xtnData->advertised[xtnData->numAdvertised++] = ssl_extended_master_secret_xtn; } @@ -2303,7 +2307,7 @@ ssl3_SendExtendedMasterSecretXtn(sslSocket *ss, PRBool append, } SECStatus -ssl3_HandleExtendedMasterSecretXtn(sslSocket *ss, PRUint16 ex_type, +ssl3_HandleExtendedMasterSecretXtn(const sslSocket *ss, TLSExtensionData *xtnData, PRUint16 ex_type, SECItem *data) { if (ss->version < SSL_LIBRARY_VERSION_TLS_1_0) { @@ -2324,11 +2328,11 @@ ssl3_HandleExtendedMasterSecretXtn(sslSocket *ss, PRUint16 ex_type, SSL_GETPID(), ss->fd)); /* Keep track of negotiated extensions. */ - ss->xtnData.negotiated[ss->xtnData.numNegotiated++] = ex_type; + xtnData->negotiated[xtnData->numNegotiated++] = ex_type; if (ss->sec.isServer) { - return ssl3_RegisterServerHelloExtensionSender( - ss, ex_type, ssl3_SendExtendedMasterSecretXtn); + return ssl3_RegisterExtensionSender( + ss, xtnData, ex_type, ssl3_SendExtendedMasterSecretXtn); } return SECSuccess; } @@ -2336,7 +2340,7 @@ ssl3_HandleExtendedMasterSecretXtn(sslSocket *ss, PRUint16 ex_type, /* ssl3_ClientSendSignedCertTimestampXtn sends the signed_certificate_timestamp * extension for TLS ClientHellos. */ PRInt32 -ssl3_ClientSendSignedCertTimestampXtn(sslSocket *ss, PRBool append, +ssl3_ClientSendSignedCertTimestampXtn(const sslSocket *ss, TLSExtensionData *xtnData, PRBool append, PRUint32 maxBytes) { PRInt32 extension_length = 2 /* extension_type */ + @@ -2349,16 +2353,16 @@ ssl3_ClientSendSignedCertTimestampXtn(sslSocket *ss, PRBool append, if (append && maxBytes >= extension_length) { SECStatus rv; /* extension_type */ - rv = ssl3_AppendHandshakeNumber(ss, - ssl_signed_cert_timestamp_xtn, - 2); + rv = ssl3_ExtAppendHandshakeNumber(ss, + ssl_signed_cert_timestamp_xtn, + 2); if (rv != SECSuccess) goto loser; /* zero length */ - rv = ssl3_AppendHandshakeNumber(ss, 0, 2); + rv = ssl3_ExtAppendHandshakeNumber(ss, 0, 2); if (rv != SECSuccess) goto loser; - ss->xtnData.advertised[ss->xtnData.numAdvertised++] = + xtnData->advertised[xtnData->numAdvertised++] = ssl_signed_cert_timestamp_xtn; } else if (maxBytes < extension_length) { PORT_Assert(0); @@ -2371,7 +2375,7 @@ ssl3_ClientSendSignedCertTimestampXtn(sslSocket *ss, PRBool append, } SECStatus -ssl3_ClientHandleSignedCertTimestampXtn(sslSocket *ss, PRUint16 ex_type, +ssl3_ClientHandleSignedCertTimestampXtn(const sslSocket *ss, TLSExtensionData *xtnData, PRUint16 ex_type, SECItem *data) { /* We do not yet know whether we'll be resuming a session or creating @@ -2382,7 +2386,7 @@ ssl3_ClientHandleSignedCertTimestampXtn(sslSocket *ss, PRUint16 ex_type, * All parsing is currently left to the application and we accept * everything, including empty data. */ - SECItem *scts = &ss->xtnData.signedCertTimestamps; + SECItem *scts = &xtnData->signedCertTimestamps; PORT_Assert(!scts->data && !scts->len); if (!data->len) { @@ -2391,12 +2395,12 @@ ssl3_ClientHandleSignedCertTimestampXtn(sslSocket *ss, PRUint16 ex_type, } *scts = *data; /* Keep track of negotiated extensions. */ - ss->xtnData.negotiated[ss->xtnData.numNegotiated++] = ex_type; + xtnData->negotiated[xtnData->numNegotiated++] = ex_type; return SECSuccess; } PRInt32 -ssl3_ServerSendSignedCertTimestampXtn(sslSocket *ss, +ssl3_ServerSendSignedCertTimestampXtn(const sslSocket *ss, TLSExtensionData *xtnData, PRBool append, PRUint32 maxBytes) { @@ -2419,13 +2423,13 @@ ssl3_ServerSendSignedCertTimestampXtn(sslSocket *ss, if (append) { SECStatus rv; /* extension_type */ - rv = ssl3_AppendHandshakeNumber(ss, - ssl_signed_cert_timestamp_xtn, - 2); + rv = ssl3_ExtAppendHandshakeNumber(ss, + ssl_signed_cert_timestamp_xtn, + 2); if (rv != SECSuccess) goto loser; /* extension_data */ - rv = ssl3_AppendHandshakeVariable(ss, scts->data, scts->len, 2); + rv = ssl3_ExtAppendHandshakeVariable(ss, scts->data, scts->len, 2); if (rv != SECSuccess) goto loser; } @@ -2437,11 +2441,140 @@ ssl3_ServerSendSignedCertTimestampXtn(sslSocket *ss, } SECStatus -ssl3_ServerHandleSignedCertTimestampXtn(sslSocket *ss, PRUint16 ex_type, +ssl3_ServerHandleSignedCertTimestampXtn(const sslSocket *ss, + TLSExtensionData *xtnData, + PRUint16 ex_type, SECItem *data) { - ss->xtnData.negotiated[ss->xtnData.numNegotiated++] = ex_type; + xtnData->negotiated[xtnData->numNegotiated++] = ex_type; PORT_Assert(ss->sec.isServer); - return ssl3_RegisterServerHelloExtensionSender(ss, ex_type, - ssl3_ServerSendSignedCertTimestampXtn); + return ssl3_RegisterExtensionSender( + ss, xtnData, ex_type, ssl3_ServerSendSignedCertTimestampXtn); +} + +/* Just make sure that the remote client supports uncompressed points, + * Since that is all we support. Disable ECC cipher suites if it doesn't. + */ +SECStatus +ssl3_HandleSupportedPointFormatsXtn(const sslSocket *ss, TLSExtensionData *xtnData, + PRUint16 ex_type, + SECItem *data) +{ + int i; + + if (data->len < 2 || data->len > 255 || !data->data || + data->len != (unsigned int)data->data[0] + 1) { + ssl3_ExtDecodeError(ss); + return SECFailure; + } + for (i = data->len; --i > 0;) { + if (data->data[i] == 0) { + /* indicate that we should send a reply */ + SECStatus rv; + rv = ssl3_RegisterExtensionSender(ss, xtnData, ex_type, + &ssl3_SendSupportedPointFormatsXtn); + return rv; + } + } + + /* Poor client doesn't support uncompressed points. */ + PORT_SetError(SSL_ERROR_RX_MALFORMED_HANDSHAKE); + return SECFailure; +} + +static SECStatus +ssl_UpdateSupportedGroups(sslSocket *ss, SECItem *data) +{ + PRInt32 list_len; + unsigned int i; + const sslNamedGroupDef *enabled[SSL_NAMED_GROUP_COUNT] = { 0 }; + PORT_Assert(SSL_NAMED_GROUP_COUNT == PR_ARRAY_SIZE(enabled)); + + if (!data->data || data->len < 4) { + (void)ssl3_DecodeError(ss); + return SECFailure; + } + + /* get the length of elliptic_curve_list */ + list_len = ssl3_ConsumeHandshakeNumber(ss, 2, &data->data, &data->len); + if (list_len < 0 || data->len != list_len || (data->len % 2) != 0) { + (void)ssl3_DecodeError(ss); + return SECFailure; + } + + /* disable all groups and remember the enabled groups */ + for (i = 0; i < SSL_NAMED_GROUP_COUNT; ++i) { + enabled[i] = ss->namedGroupPreferences[i]; + ss->namedGroupPreferences[i] = NULL; + } + + /* Read groups from data and enable if in |enabled| */ + while (data->len) { + const sslNamedGroupDef *group; + PRInt32 curve_name = + ssl3_ConsumeHandshakeNumber(ss, 2, &data->data, &data->len); + if (curve_name < 0) { + return SECFailure; /* fatal alert already sent */ + } + group = ssl_LookupNamedGroup(curve_name); + if (group) { + for (i = 0; i < SSL_NAMED_GROUP_COUNT; ++i) { + if (enabled[i] && group == enabled[i]) { + ss->namedGroupPreferences[i] = enabled[i]; + break; + } + } + } + + /* "Codepoints in the NamedCurve registry with a high byte of 0x01 (that + * is, between 256 and 511 inclusive) are set aside for FFDHE groups," + * -- https://tools.ietf.org/html/draft-ietf-tls-negotiated-ff-dhe-10 + */ + if ((curve_name & 0xff00) == 0x0100) { + ss->xtnData.peerSupportsFfdheGroups = PR_TRUE; + } + } + + /* Note: if ss->opt.requireDHENamedGroups is set, we disable DHE cipher + * suites, but we do that in ssl3_config_match(). */ + if (ss->version < SSL_LIBRARY_VERSION_TLS_1_3 && + !ss->opt.requireDHENamedGroups && !ss->xtnData.peerSupportsFfdheGroups) { + /* If we don't require that DHE use named groups, and no FFDHE was + * included, we pretend that they support all the FFDHE groups we do. */ + for (i = 0; i < SSL_NAMED_GROUP_COUNT; ++i) { + if (enabled[i] && enabled[i]->keaType == ssl_kea_dh) { + ss->namedGroupPreferences[i] = enabled[i]; + } + } + } + + return SECSuccess; +} + +/* Ensure that the curve in our server cert is one of the ones supported + * by the remote client, and disable all ECC cipher suites if not. + */ +SECStatus +ssl_HandleSupportedGroupsXtn(const sslSocket *ss, TLSExtensionData *xtnData, + PRUint16 ex_type, SECItem *data) +{ + SECStatus rv; + + rv = ssl_UpdateSupportedGroups(CONST_CAST(sslSocket, ss), data); + if (rv != SECSuccess) + return SECFailure; + + /* TLS 1.3 permits the server to send this extension so make it so. */ + if (ss->sec.isServer && ss->version >= SSL_LIBRARY_VERSION_TLS_1_3) { + rv = ssl3_RegisterExtensionSender(ss, xtnData, ex_type, + &ssl_SendSupportedGroupsXtn); + if (rv != SECSuccess) { + return SECFailure; /* error already set. */ + } + } + + /* Remember that we negotiated this extension. */ + xtnData->negotiated[xtnData->numNegotiated++] = ex_type; + + return SECSuccess; } diff --git a/lib/ssl/ssl3exthandle.h b/lib/ssl/ssl3exthandle.h index ef15260bfe..65223d6fd1 100644 --- a/lib/ssl/ssl3exthandle.h +++ b/lib/ssl/ssl3exthandle.h @@ -9,63 +9,87 @@ #ifndef __ssl3exthandle_h_ #define __ssl3exthandle_h_ -PRInt32 ssl3_SendRenegotiationInfoXtn(sslSocket *ss, +PRInt32 ssl3_SendRenegotiationInfoXtn(const sslSocket *ss, TLSExtensionData *xtnData, PRBool append, PRUint32 maxBytes); -SECStatus ssl3_HandleRenegotiationInfoXtn(sslSocket *ss, +SECStatus ssl3_HandleRenegotiationInfoXtn(const sslSocket *ss, TLSExtensionData *xtnData, PRUint16 ex_type, SECItem *data); -SECStatus ssl3_ClientHandleNextProtoNegoXtn(sslSocket *ss, +SECStatus ssl3_ClientHandleNextProtoNegoXtn(const sslSocket *ss, TLSExtensionData *xtnData, PRUint16 ex_type, SECItem *data); -SECStatus ssl3_ClientHandleAppProtoXtn(sslSocket *ss, +SECStatus ssl3_ClientHandleAppProtoXtn(const sslSocket *ss, TLSExtensionData *xtnData, PRUint16 ex_type, SECItem *data); -SECStatus ssl3_ServerHandleNextProtoNegoXtn(sslSocket *ss, +SECStatus ssl3_ServerHandleNextProtoNegoXtn(const sslSocket *ss, TLSExtensionData *xtnData, PRUint16 ex_type, SECItem *data); -SECStatus ssl3_ServerHandleAppProtoXtn(sslSocket *ss, PRUint16 ex_type, +SECStatus ssl3_ServerHandleAppProtoXtn(const sslSocket *ss, TLSExtensionData *xtnData, PRUint16 ex_type, SECItem *data); -PRInt32 ssl3_ClientSendNextProtoNegoXtn(sslSocket *ss, PRBool append, +PRInt32 ssl3_ClientSendNextProtoNegoXtn(const sslSocket *ss, TLSExtensionData *xtnData, PRBool append, PRUint32 maxBytes); -PRInt32 ssl3_ClientSendAppProtoXtn(sslSocket *ss, PRBool append, +PRInt32 ssl3_ClientSendAppProtoXtn(const sslSocket *ss, TLSExtensionData *xtnData, PRBool append, PRUint32 maxBytes); -PRInt32 ssl3_ServerSendAppProtoXtn(sslSocket *ss, PRBool append, +PRInt32 ssl3_ServerSendAppProtoXtn(const sslSocket *ss, TLSExtensionData *xtnData, PRBool append, PRUint32 maxBytes); -PRInt32 ssl3_ClientSendUseSRTPXtn(sslSocket *ss, PRBool append, +PRInt32 ssl3_ClientSendUseSRTPXtn(const sslSocket *ss, TLSExtensionData *xtnData, PRBool append, PRUint32 maxBytes); -PRInt32 ssl3_ServerSendUseSRTPXtn(sslSocket *ss, PRBool append, +PRInt32 ssl3_ServerSendUseSRTPXtn(const sslSocket *ss, TLSExtensionData *xtnData, PRBool append, PRUint32 maxBytes); -SECStatus ssl3_ClientHandleUseSRTPXtn(sslSocket *ss, PRUint16 ex_type, +SECStatus ssl3_ClientHandleUseSRTPXtn(const sslSocket *ss, TLSExtensionData *xtnData, PRUint16 ex_type, SECItem *data); -SECStatus ssl3_ServerHandleUseSRTPXtn(sslSocket *ss, PRUint16 ex_type, +SECStatus ssl3_ServerHandleUseSRTPXtn(const sslSocket *ss, TLSExtensionData *xtnData, PRUint16 ex_type, SECItem *data); -PRInt32 ssl3_ServerSendStatusRequestXtn(sslSocket *ss, +PRInt32 ssl3_ServerSendStatusRequestXtn(const sslSocket *ss, TLSExtensionData *xtnData, PRBool append, PRUint32 maxBytes); -SECStatus ssl3_ServerHandleStatusRequestXtn(sslSocket *ss, +SECStatus ssl3_ServerHandleStatusRequestXtn(const sslSocket *ss, TLSExtensionData *xtnData, PRUint16 ex_type, SECItem *data); -SECStatus ssl3_ClientHandleStatusRequestXtn(sslSocket *ss, +SECStatus ssl3_ClientHandleStatusRequestXtn(const sslSocket *ss, TLSExtensionData *xtnData, PRUint16 ex_type, SECItem *data); -PRInt32 ssl3_ClientSendStatusRequestXtn(sslSocket *ss, PRBool append, +PRInt32 ssl3_ClientSendStatusRequestXtn(const sslSocket *ss, TLSExtensionData *xtnData, PRBool append, PRUint32 maxBytes); -PRInt32 ssl3_ClientSendSigAlgsXtn(sslSocket *ss, PRBool append, +PRInt32 ssl3_ClientSendSigAlgsXtn(const sslSocket *ss, TLSExtensionData *xtnData, PRBool append, PRUint32 maxBytes); -SECStatus ssl3_ServerHandleSigAlgsXtn(sslSocket *ss, PRUint16 ex_type, +SECStatus ssl3_ServerHandleSigAlgsXtn(const sslSocket *ss, TLSExtensionData *xtnData, PRUint16 ex_type, SECItem *data); -PRInt32 ssl3_ClientSendSignedCertTimestampXtn(sslSocket *ss, +PRInt32 ssl3_ClientSendSignedCertTimestampXtn(const sslSocket *ss, TLSExtensionData *xtnData, PRBool append, PRUint32 maxBytes); -SECStatus ssl3_ClientHandleSignedCertTimestampXtn(sslSocket *ss, +SECStatus ssl3_ClientHandleSignedCertTimestampXtn(const sslSocket *ss, TLSExtensionData *xtnData, PRUint16 ex_type, SECItem *data); -PRInt32 ssl3_ServerSendSignedCertTimestampXtn(sslSocket *ss, +PRInt32 ssl3_ServerSendSignedCertTimestampXtn(const sslSocket *ss, TLSExtensionData *xtnData, PRBool append, PRUint32 maxBytes); -SECStatus ssl3_ServerHandleSignedCertTimestampXtn(sslSocket *ss, +SECStatus ssl3_ServerHandleSignedCertTimestampXtn(const sslSocket *ss, TLSExtensionData *xtnData, PRUint16 ex_type, SECItem *data); -PRInt32 ssl3_SendExtendedMasterSecretXtn(sslSocket *ss, PRBool append, +PRInt32 ssl3_SendExtendedMasterSecretXtn(const sslSocket *ss, TLSExtensionData *xtnData, PRBool append, PRUint32 maxBytes); -SECStatus ssl3_HandleExtendedMasterSecretXtn(sslSocket *ss, +SECStatus ssl3_HandleExtendedMasterSecretXtn(const sslSocket *ss, TLSExtensionData *xtnData, PRUint16 ex_type, SECItem *data); SECStatus ssl3_ProcessSessionTicketCommon(sslSocket *ss, SECItem *data); +PRInt32 ssl3_SendServerNameXtn(const sslSocket *ss, + TLSExtensionData *xtnData, + PRBool append, + PRUint32 maxBytes); +SECStatus ssl3_HandleServerNameXtn(const sslSocket *ss, TLSExtensionData *xtnData, + PRUint16 ex_type, SECItem *data); +SECStatus ssl_HandleSupportedGroupsXtn(const sslSocket *ss, TLSExtensionData *xtnData, + PRUint16 ex_type, SECItem *data); +SECStatus ssl3_HandleSupportedPointFormatsXtn(const sslSocket *ss, TLSExtensionData *xtnData, + PRUint16 ex_type, SECItem *data); +SECStatus ssl3_ClientHandleSessionTicketXtn(const sslSocket *ss, TLSExtensionData *xtnData, + PRUint16 ex_type, SECItem *data); +SECStatus ssl3_ServerHandleSessionTicketXtn(const sslSocket *ss, TLSExtensionData *xtnData, + PRUint16 ex_type, SECItem *data); +PRInt32 ssl3_SendSessionTicketXtn(const sslSocket *ss, + TLSExtensionData *xtnData, + PRBool append, + PRUint32 maxBytes); +PRInt32 ssl_SendSupportedGroupsXtn(const sslSocket *ss, + TLSExtensionData *xtnData, + PRBool append, PRUint32 maxBytes); +PRInt32 ssl3_SendSupportedPointFormatsXtn(const sslSocket *ss, + TLSExtensionData *xtnData, + PRBool append, PRUint32 maxBytes); #endif diff --git a/lib/ssl/sslimpl.h b/lib/ssl/sslimpl.h index d75cf0d0cf..06a968463a 100644 --- a/lib/ssl/sslimpl.h +++ b/lib/ssl/sslimpl.h @@ -33,6 +33,10 @@ #include "sslt.h" /* for some formerly private types, now public */ +typedef struct sslSocketStr sslSocket; + +#include "ssl3ext.h" + /* to make some of these old enums public without namespace pollution, ** it was necessary to prepend ssl_ to the names. ** These #defines preserve compatibility with the old code here in libssl. @@ -102,6 +106,8 @@ extern int Debug; #define LSB(x) ((unsigned char)((x)&0xff)) #define MSB(x) ((unsigned char)(((unsigned)(x)) >> 8)) +#define CONST_CAST(T, X) ((T *)(X)) + /************************************************************************/ typedef enum { SSLAppOpRead = 0, @@ -172,7 +178,6 @@ typedef struct sslConnectInfoStr sslConnectInfo; typedef struct sslGatherStr sslGather; typedef struct sslSecurityInfoStr sslSecurityInfo; typedef struct sslSessionIDStr sslSessionID; -typedef struct sslSocketStr sslSocket; typedef struct sslSocketOpsStr sslSocketOps; typedef struct ssl3StateStr ssl3State; @@ -196,46 +201,6 @@ typedef sslSessionID *(*sslSessionIDLookupFunc)(const PRIPv6Addr *addr, unsigned int sidLen, CERTCertDBHandle *dbHandle); -/* registerable callback function that either appends extension to buffer - * or returns length of data that it would have appended. - */ -typedef PRInt32 (*ssl3HelloExtensionSenderFunc)(sslSocket *ss, PRBool append, - PRUint32 maxBytes); - -/* registerable callback function that handles a received extension, - * of the given type. - */ -typedef SECStatus (*ssl3ExtensionHandlerFunc)(sslSocket *ss, - PRUint16 ex_type, - SECItem *data); - -/* row in a table of hello extension senders */ -typedef struct { - PRInt32 ex_type; - ssl3HelloExtensionSenderFunc ex_sender; -} ssl3HelloExtensionSender; - -/* row in a table of hello extension handlers */ -typedef struct { - PRInt32 ex_type; - ssl3ExtensionHandlerFunc ex_handler; -} ssl3ExtensionHandler; - -extern SECStatus -ssl3_RegisterServerHelloExtensionSender(sslSocket *ss, PRUint16 ex_type, - ssl3HelloExtensionSenderFunc cb); - -extern PRInt32 -ssl3_CallHelloExtensionSenders(sslSocket *ss, PRBool append, PRUint32 maxBytes, - const ssl3HelloExtensionSender *sender); - -extern unsigned int -ssl3_CalculatePaddingExtensionLength(unsigned int clientHelloLength); - -extern PRInt32 -ssl3_AppendPaddingExtension(sslSocket *ss, unsigned int extensionLen, - PRUint32 maxBytes); - /* Socket ops */ struct sslSocketOpsStr { int (*connect)(sslSocket *, const PRNetAddr *); @@ -754,53 +719,8 @@ typedef enum { /* * TLS extension related constants and data structures. */ -typedef struct TLSExtensionDataStr TLSExtensionData; typedef struct SessionTicketDataStr SessionTicketData; -struct TLSExtensionDataStr { - /* registered callbacks that send server hello extensions */ - ssl3HelloExtensionSender serverHelloSenders[SSL_MAX_EXTENSIONS]; - ssl3HelloExtensionSender encryptedExtensionsSenders[SSL_MAX_EXTENSIONS]; - - /* Keep track of the extensions that are negotiated. */ - PRUint16 numAdvertised; - PRUint16 numNegotiated; - PRUint16 advertised[SSL_MAX_EXTENSIONS]; - PRUint16 negotiated[SSL_MAX_EXTENSIONS]; - - /* SessionTicket Extension related data. */ - PRBool ticketTimestampVerified; - PRBool emptySessionTicket; - PRBool sentSessionTicketInClientHello; - SECItem psk_ke_modes; - SECItem psk_auth_modes; - PRUint32 ticket_age_add; - PRBool ticket_age_add_found; - - /* SNI Extension related data - * Names data is not coppied from the input buffer. It can not be - * used outside the scope where input buffer is defined and that - * is beyond ssl3_HandleClientHello function. */ - SECItem *sniNameArr; - PRUint32 sniNameArrSize; - - /* Signed Certificate Timestamps extracted from the TLS extension. - * (client only). - * This container holds a temporary pointer to the extension data, - * until a session structure (the sec.ci.sid of an sslSocket) is setup - * that can hold a permanent copy of the data - * (in sec.ci.sid.u.ssl3.signedCertTimestamps). - * The data pointed to by this structure is neither explicitly allocated - * nor copied: the pointer points to the handshake message buffer and is - * only valid in the scope of ssl3_HandleServerHello. - */ - SECItem signedCertTimestamps; -}; - -typedef enum { - sni_nametype_hostname -} SNINameType; - typedef SECStatus (*sslRestartTarget)(sslSocket *); /* @@ -830,12 +750,6 @@ typedef struct { unsigned int len; } TLS13CombinedHash; -typedef struct TLSExtensionStr { - PRCList link; /* The linked list link */ - PRUint16 type; /* Extension type */ - SECItem data; /* Pointers into the handshake data. */ -} TLSExtension; - typedef enum { handshake_hash_unknown = 0, handshake_hash_combo = 1, /* The MD5/SHA-1 combination */ @@ -913,14 +827,6 @@ typedef struct SSL3HandshakeStateStr { /* Which preliminaryinfo values have been set. */ PRUint32 preliminaryInfo; - 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; - /* Parsed extensions */ PRCList remoteExtensions; /* Parsed incoming extensions */ @@ -950,7 +856,6 @@ typedef struct SSL3HandshakeStateStr { /* This group of values is used for TLS 1.3 and above */ PK11Context *clientHelloHash; /* The client hello hash state, used * by the server for 0-RTT. */ - PRCList remoteKeyShares; /* The other side's public keys */ PK11SymKey *currentSecret; /* The secret down the "left hand side" * of the TLS 1.3 key schedule. */ PK11SymKey *resumptionPsk; /* The resumption PSK. */ @@ -1014,18 +919,11 @@ struct ssl3StateStr { SSL3HandshakeState hs; ssl3CipherSpec specs[2]; /* one is current, one is pending. */ - /* In a client: if the server supports Next Protocol Negotiation, then - * this is the protocol that was negotiated. - */ - SECItem nextProto; - SSLNextProtoState nextProtoState; - PRUint16 mtu; /* Our estimate of the MTU */ /* DTLS-SRTP cipher suite preferences (if any) */ PRUint16 dtlsSRTPCiphers[MAX_DTLS_SRTP_CIPHER_SUITES]; PRUint16 dtlsSRTPCipherCount; - PRUint16 dtlsSRTPCipherSuite; /* 0 if not selected */ PRBool fatalAlertSent; PRBool dheWeakGroupEnabled; /* used by server */ const sslNamedGroupDef *dhePreferredGroup; @@ -1664,10 +1562,12 @@ extern sslEphemeralKeyPair *ssl_CopyEphemeralKeyPair( extern void ssl_FreeEphemeralKeyPair(sslEphemeralKeyPair *keyPair); extern sslEphemeralKeyPair *ssl_LookupEphemeralKeyPair( sslSocket *ss, const sslNamedGroupDef *groupDef); +extern PRBool ssl_HaveEphemeralKeyPair(const sslSocket *ss, + const sslNamedGroupDef *groupDef); extern void ssl_FreeEphemeralKeyPairs(sslSocket *ss); -extern SECStatus ssl_AppendPaddedDHKeyShare(sslSocket *ss, - SECKEYPublicKey *pubKey, +extern SECStatus ssl_AppendPaddedDHKeyShare(const sslSocket *ss, + const SECKEYPublicKey *pubKey, PRBool appendLength); extern const ssl3DHParams *ssl_GetDHEParams(const sslNamedGroupDef *groupDef); extern SECStatus ssl_SelectDHEGroup(sslSocket *ss, @@ -1682,8 +1582,8 @@ extern SECStatus ssl_ValidateDHENamedGroup(sslSocket *ss, const sslNamedGroupDef **groupDef, const ssl3DHParams **dhParams); -extern PRBool ssl_IsECCEnabled(sslSocket *ss); -extern PRBool ssl_IsDHEEnabled(sslSocket *ss); +extern PRBool ssl_IsECCEnabled(const sslSocket *ss); +extern PRBool ssl_IsDHEEnabled(const sslSocket *ss); /* Macro for finding a curve equivalent in strength to RSA key's */ #define SSL_RSASTRENGTH_TO_ECSTRENGTH(s) \ @@ -1708,7 +1608,7 @@ extern SECStatus ssl3_CipherPrefSetDefault(ssl3CipherSuite which, PRBool on); extern SECStatus ssl3_CipherPrefGetDefault(ssl3CipherSuite which, PRBool *on); extern SECStatus ssl3_CipherPrefSet(sslSocket *ss, ssl3CipherSuite which, PRBool on); -extern SECStatus ssl3_CipherPrefGet(sslSocket *ss, ssl3CipherSuite which, PRBool *on); +extern SECStatus ssl3_CipherPrefGet(const sslSocket *ss, ssl3CipherSuite which, PRBool *on); extern SECStatus ssl3_SetPolicy(ssl3CipherSuite which, PRInt32 policy); extern SECStatus ssl3_GetPolicy(ssl3CipherSuite which, PRInt32 *policy); @@ -1744,7 +1644,7 @@ extern SECStatus ssl_ImportECDHKeyShare( sslSocket *ss, SECKEYPublicKey *peerKey, SSL3Opaque *b, PRUint32 length, const sslNamedGroupDef *curve); unsigned int tls13_SizeOfECDHEKeyShareKEX(const SECKEYPublicKey *pubKey); -SECStatus tls13_EncodeECDHEKeyShareKEX(sslSocket *ss, +SECStatus tls13_EncodeECDHEKeyShareKEX(const sslSocket *ss, const SECKEYPublicKey *pubKey); extern SECStatus ssl3_ComputeCommonKeyHash(SSLHashType hashAlg, @@ -1775,7 +1675,7 @@ extern PRUint8 *ssl_EncodeUintX(PRUint64 value, unsigned int bytes, extern PRBool ssl_IsSupportedSignatureScheme(SSLSignatureScheme scheme); extern SECStatus ssl_CheckSignatureSchemeConsistency( sslSocket *ss, SSLSignatureScheme scheme, CERTCertificate *cert); -extern SECStatus ssl_ParseSignatureSchemes(sslSocket *ss, PLArenaPool *arena, +extern SECStatus ssl_ParseSignatureSchemes(const sslSocket *ss, PLArenaPool *arena, SSLSignatureScheme **schemesOut, unsigned int *numSchemesOut, unsigned char **b, @@ -1791,50 +1691,7 @@ extern SECStatus ssl3_CacheWrappedMasterSecret( ssl3CipherSpec *spec, SSLAuthType authType); extern void ssl3_FreeSniNameArray(TLSExtensionData *xtnData); -/* Functions that handle ClientHello and ServerHello extensions. */ -extern SECStatus ssl3_HandleServerNameXtn(sslSocket *ss, - PRUint16 ex_type, SECItem *data); -extern SECStatus ssl_HandleSupportedGroupsXtn(sslSocket *ss, - PRUint16 ex_type, SECItem *data); -extern SECStatus ssl3_HandleSupportedPointFormatsXtn(sslSocket *ss, - PRUint16 ex_type, SECItem *data); -extern SECStatus ssl3_ClientHandleSessionTicketXtn(sslSocket *ss, - PRUint16 ex_type, SECItem *data); -extern SECStatus ssl3_ServerHandleSessionTicketXtn(sslSocket *ss, - PRUint16 ex_type, SECItem *data); - -/* ClientHello and ServerHello extension senders. - * Note that not all extension senders are exposed here; only those that - * that need exposure. - */ -extern PRInt32 ssl3_SendSessionTicketXtn(sslSocket *ss, PRBool append, - PRUint32 maxBytes); - -/* ClientHello and ServerHello extension senders. - * The code is in ssl3ext.c. - */ -extern PRInt32 ssl3_SendServerNameXtn(sslSocket *ss, PRBool append, - PRUint32 maxBytes); - -extern PRInt32 ssl_SendSupportedGroupsXtn(sslSocket *ss, - PRBool append, PRUint32 maxBytes); -extern PRInt32 ssl3_SendSupportedPointFormatsXtn(sslSocket *ss, - PRBool append, PRUint32 maxBytes); - -/* call the registered extension handlers. */ -extern SECStatus ssl3_HandleExtensions(sslSocket *ss, - SSL3Opaque **b, PRUint32 *length, - SSL3HandshakeType handshakeMessage); -extern SECStatus ssl3_ParseExtensions(sslSocket *ss, - SSL3Opaque **b, PRUint32 *length); -extern SECStatus ssl3_HandleParsedExtensions(sslSocket *ss, - SSL3HandshakeType handshakeMessage); -extern TLSExtension *ssl3_FindExtension(sslSocket *ss, - SSLExtensionType extension_type); -extern void ssl3_DestroyRemoteExtensions(PRCList *list); - /* Hello Extension related routines. */ -extern PRBool ssl3_ExtensionNegotiated(sslSocket *ss, PRUint16 ex_type); extern void ssl3_SetSIDSessionTicket(sslSessionID *sid, /*in/out*/ NewSessionTicket *session_ticket); SECStatus ssl3_EncodeSessionTicket(sslSocket *ss, @@ -1940,7 +1797,7 @@ SECStatus ssl3_SendEmptyCertificate(sslSocket *ss); SECStatus ssl3_SendCertificateStatus(sslSocket *ss); SECStatus ssl_ReadCertificateStatus(sslSocket *ss, SSL3Opaque *b, PRUint32 length); -SECStatus ssl3_EncodeSigAlgs(sslSocket *ss, PRUint8 *buf, +SECStatus ssl3_EncodeSigAlgs(const sslSocket *ss, PRUint8 *buf, unsigned maxLen, PRUint32 *len); void ssl3_GetCertificateRequestCAs(sslSocket *ss, int *calenp, SECItem **namesp, int *nnamesp); @@ -1955,8 +1812,6 @@ SECStatus ssl3_ComputeHandshakeHashes(sslSocket *ss, ssl3CipherSpec *spec, SSL3Hashes *hashes, PRUint32 sender); -PRInt32 tls13_ServerSendKeyShareXtn(sslSocket *ss, PRBool append, - PRUint32 maxBytes); SECStatus ssl_CreateECDHEphemeralKeyPair(const sslSocket *ss, const sslNamedGroupDef *ecGroup, sslEphemeralKeyPair **keyPair); @@ -1968,16 +1823,6 @@ PK11SymKey *ssl3_GetWrappingKey(sslSocket *ss, const sslServerCert *serverCert, CK_MECHANISM_TYPE masterWrapMech, void *pwArg); -PRInt32 tls13_ServerSendPreSharedKeyXtn(sslSocket *ss, - PRBool append, - PRUint32 maxBytes); -PRInt32 tls13_ServerSendEarlyDataXtn(sslSocket *ss, - PRBool append, - PRUint32 maxBytes); -PRInt32 tls13_ServerSendSigAlgsXtn(sslSocket *ss, - PRBool append, - PRUint32 maxBytes); -PRBool ssl3_ClientExtensionAdvertised(sslSocket *ss, PRUint16 ex_type); SECStatus ssl3_FillInCachedSID(sslSocket *ss, sslSessionID *sid); const ssl3CipherSuiteDef *ssl_LookupCipherSuiteDef(ssl3CipherSuite suite); const ssl3BulkCipherDef * diff --git a/lib/ssl/sslsecur.c b/lib/ssl/sslsecur.c index 11d8aaa1f4..eecf443967 100644 --- a/lib/ssl/sslsecur.c +++ b/lib/ssl/sslsecur.c @@ -200,6 +200,7 @@ SSL_ResetHandshake(PRFileDesc *s, PRBool asServer) ssl_Release1stHandshakeLock(ss); ssl3_DestroyRemoteExtensions(&ss->ssl3.hs.remoteExtensions); + ssl3_ResetExtensionData(&ss->xtnData); if (!ss->TCPconnected) ss->TCPconnected = (PR_SUCCESS == ssl_DefGetpeername(ss, &addr)); diff --git a/lib/ssl/sslsock.c b/lib/ssl/sslsock.c index 42dc06a5ee..7923bb80c7 100644 --- a/lib/ssl/sslsock.c +++ b/lib/ssl/sslsock.c @@ -1760,7 +1760,7 @@ ssl_SelectDHEGroup(sslSocket *ss, const sslNamedGroupDef **groupDef) * indicated that it supports an FFDHE named group. */ if (ss->ssl3.dheWeakGroupEnabled && ss->version < SSL_LIBRARY_VERSION_TLS_1_3 && - !ss->ssl3.hs.peerSupportsFfdheGroups) { + !ss->xtnData.peerSupportsFfdheGroups) { *groupDef = &weak_group_def; return SECSuccess; } @@ -1889,7 +1889,7 @@ ssl_NextProtoNegoCallback(void *arg, PRFileDesc *fd, PORT_Memcmp(&protos[i + 1], &ss->opt.nextProtoNego.data[j + 1], protos[i]) == 0) { /* We found a match. */ - ss->ssl3.nextProtoState = SSL_NEXT_PROTO_NEGOTIATED; + ss->xtnData.nextProtoState = SSL_NEXT_PROTO_NEGOTIATED; result = &protos[i]; goto found; } @@ -1902,7 +1902,7 @@ ssl_NextProtoNegoCallback(void *arg, PRFileDesc *fd, * protocols configured, or none of its options match ours. In this case we * request our favoured protocol. */ /* This will be treated as a failure for ALPN. */ - ss->ssl3.nextProtoState = SSL_NEXT_PROTO_NO_OVERLAP; + ss->xtnData.nextProtoState = SSL_NEXT_PROTO_NO_OVERLAP; result = ss->opt.nextProtoNego.data; found: @@ -1961,16 +1961,16 @@ SSL_GetNextProto(PRFileDesc *fd, SSLNextProtoState *state, unsigned char *buf, return SECFailure; } - *state = ss->ssl3.nextProtoState; + *state = ss->xtnData.nextProtoState; - if (ss->ssl3.nextProtoState != SSL_NEXT_PROTO_NO_SUPPORT && - ss->ssl3.nextProto.data) { - if (ss->ssl3.nextProto.len > bufLenMax) { + if (ss->xtnData.nextProtoState != SSL_NEXT_PROTO_NO_SUPPORT && + ss->xtnData.nextProto.data) { + if (ss->xtnData.nextProto.len > bufLenMax) { PORT_SetError(SEC_ERROR_OUTPUT_LEN); return SECFailure; } - PORT_Memcpy(buf, ss->ssl3.nextProto.data, ss->ssl3.nextProto.len); - *bufLen = ss->ssl3.nextProto.len; + PORT_Memcpy(buf, ss->xtnData.nextProto.data, ss->xtnData.nextProto.len); + *bufLen = ss->xtnData.nextProto.len; } else { *bufLen = 0; } @@ -2040,12 +2040,12 @@ SSL_GetSRTPCipher(PRFileDesc *fd, PRUint16 *cipher) return SECFailure; } - if (!ss->ssl3.dtlsSRTPCipherSuite) { + if (!ss->xtnData.dtlsSRTPCipherSuite) { PORT_SetError(SEC_ERROR_INVALID_ARGS); return SECFailure; } - *cipher = ss->ssl3.dtlsSRTPCipherSuite; + *cipher = ss->xtnData.dtlsSRTPCipherSuite; return SECSuccess; } @@ -3606,6 +3606,12 @@ ssl_FreeEphemeralKeyPair(sslEphemeralKeyPair *keyPair) PORT_Free(keyPair); } +PRBool +ssl_HaveEphemeralKeyPair(const sslSocket *ss, const sslNamedGroupDef *groupDef) +{ + return ssl_LookupEphemeralKeyPair((sslSocket *)ss, groupDef) != NULL; +} + sslEphemeralKeyPair * ssl_LookupEphemeralKeyPair(sslSocket *ss, const sslNamedGroupDef *groupDef) { @@ -3688,7 +3694,6 @@ ssl_NewSocket(PRBool makeLocks, SSLProtocolVariant protocolVariant) ss->additionalShares = 0; PR_INIT_CLIST(&ss->ssl3.hs.remoteExtensions); PR_INIT_CLIST(&ss->ssl3.hs.lastMessageFlight); - PR_INIT_CLIST(&ss->ssl3.hs.remoteKeyShares); PR_INIT_CLIST(&ss->ssl3.hs.cipherSpecs); PR_INIT_CLIST(&ss->ssl3.hs.bufferedEarlyData); if (makeLocks) { @@ -3702,7 +3707,7 @@ ssl_NewSocket(PRBool makeLocks, SSLProtocolVariant protocolVariant) rv = ssl3_InitGather(&ss->gs); if (rv != SECSuccess) goto loser; - + ssl3_InitExtensionData(&ss->xtnData); return ss; loser: diff --git a/lib/ssl/tls13con.c b/lib/ssl/tls13con.c index 695483252a..0ae34b9f46 100644 --- a/lib/ssl/tls13con.c +++ b/lib/ssl/tls13con.c @@ -19,6 +19,7 @@ #include "sslerr.h" #include "tls13hkdf.h" #include "tls13con.h" +#include "tls13exthandle.h" typedef enum { TrafficKeyEarlyHandshake, @@ -976,7 +977,7 @@ tls13_CanResume(sslSocket *ss, const sslSessionID *sid) } static PRBool -tls13_AlpnTagAllowed(sslSocket *ss, const SECItem *tag) +tls13_AlpnTagAllowed(const sslSocket *ss, const SECItem *tag) { const unsigned char *data = ss->opt.nextProtoNego.data; unsigned int length = ss->opt.nextProtoNego.len; @@ -1030,7 +1031,7 @@ tls13_NegotiateZeroRtt(sslSocket *ss, const sslSessionID *sid) PORT_Assert(ss->ssl3.hs.zeroRttState == ssl_0rtt_sent); if (sid && ss->opt.enable0RttData && (sid->u.ssl3.locked.sessionTicket.flags & ticket_allow_early_data) != 0 && - SECITEM_CompareItem(&ss->ssl3.nextProto, &sid->u.ssl3.alpnSelection) == 0) { + SECITEM_CompareItem(&ss->xtnData.nextProto, &sid->u.ssl3.alpnSelection) == 0) { SSL_TRC(3, ("%d: TLS13[%d]: enable 0-RTT", SSL_GETPID(), ss->fd)); PORT_Assert(ss->statelessResume); @@ -1068,8 +1069,8 @@ tls13_isGroupAcceptable(const sslNamedGroupDef *offered, static TLS13KeyShareEntry * tls13_FindKeyShareEntry(sslSocket *ss, const sslNamedGroupDef *group) { - PRCList *cur_p = PR_NEXT_LINK(&ss->ssl3.hs.remoteKeyShares); - while (cur_p != &ss->ssl3.hs.remoteKeyShares) { + PRCList *cur_p = PR_NEXT_LINK(&ss->xtnData.remoteKeyShares); + while (cur_p != &ss->xtnData.remoteKeyShares) { TLS13KeyShareEntry *offer = (TLS13KeyShareEntry *)cur_p; if (offer->group == group) { return offer; @@ -1155,8 +1156,6 @@ tls13_NegotiateKeyExchange(sslSocket *ss, TLS13KeyShareEntry **clientShare) SSL_TRC(3, ("%d: TLS13[%d]: group = %d", SSL_GETPID(), ss->fd, preferredGroup->name)); - SSL_TRC(3, ("%d: TLS13[%d]: group = %d", preferredGroup->name)); - if (!entry) { return tls13_SendHelloRetryRequest(ss, preferredGroup); } @@ -1198,8 +1197,8 @@ tls13_SelectServerCert(sslSocket *ss) rv = ssl_PickSignatureScheme(ss, cert->serverKeyPair->pubKey, cert->serverKeyPair->privKey, - ss->ssl3.hs.clientSigSchemes, - ss->ssl3.hs.numClientSigScheme, + ss->xtnData.clientSigSchemes, + ss->xtnData.numClientSigScheme, PR_FALSE); if (rv == SECSuccess) { /* Found one. */ @@ -1241,8 +1240,8 @@ tls13_NegotiateAuthentication(sslSocket *ss) SSL_TRC(3, ("%d: TLS13[%d]: selected certificate authentication", SSL_GETPID(), ss->fd)); - rv = ssl3_RegisterServerHelloExtensionSender( - ss, ssl_signature_algorithms_xtn, + rv = ssl3_RegisterExtensionSender( + ss, &ss->xtnData, ssl_signature_algorithms_xtn, tls13_ServerSendSigAlgsXtn); if (rv != SECSuccess) { return SECFailure; /* Error code set already. */ @@ -1272,6 +1271,20 @@ tls13_HandleClientHelloPart2(sslSocket *ss, int j; ssl3CipherSuite previousCipherSuite; + if (ssl3_ExtensionNegotiated(ss, ssl_tls13_early_data_xtn)) { + ss->ssl3.hs.zeroRttState = ssl_0rtt_sent; + + if (IS_DTLS(ss)) { + /* Save the null spec, which we should be currently reading. We will + * use this when 0-RTT sending is over. */ + ssl_GetSpecReadLock(ss); + ss->ssl3.hs.nullSpec = ss->ssl3.crSpec; + tls13_CipherSpecAddRef(ss->ssl3.hs.nullSpec); + PORT_Assert(ss->ssl3.hs.nullSpec->cipher_def->cipher == cipher_null); + ssl_ReleaseSpecReadLock(ss); + } + } + #ifndef PARANOID /* Look for a matching cipher suite. */ j = ssl3_config_match_init(ss); @@ -1367,8 +1380,9 @@ tls13_HandleClientHelloPart2(sslSocket *ss, if (sid->peerCert != NULL) { ss->sec.peerCert = CERT_DupCertificate(sid->peerCert); } - ssl3_RegisterServerHelloExtensionSender( - ss, ssl_tls13_pre_shared_key_xtn, tls13_ServerSendPreSharedKeyXtn); + ssl3_RegisterExtensionSender( + ss, &ss->xtnData, + ssl_tls13_pre_shared_key_xtn, tls13_ServerSendPreSharedKeyXtn); tls13_NegotiateZeroRtt(ss, sid); } else { @@ -1580,8 +1594,8 @@ tls13_HandleClientKeyShare(sslSocket *ss, TLS13KeyShareEntry *peerShare) ss->sec.keaKeyBits = SECKEY_PublicKeyStrengthInBits(keyPair->keys->pubKey); /* Register the sender */ - rv = ssl3_RegisterServerHelloExtensionSender(ss, ssl_tls13_key_share_xtn, - tls13_ServerSendKeyShareXtn); + rv = ssl3_RegisterExtensionSender(ss, &ss->xtnData, ssl_tls13_key_share_xtn, + tls13_ServerSendKeyShareXtn); if (rv != SECSuccess) { return SECFailure; /* Error code set already. */ } @@ -1857,8 +1871,8 @@ tls13_SendEncryptedServerSequence(sslSocket *ss) } if (ss->ssl3.hs.zeroRttState == ssl_0rtt_accepted) { - rv = ssl3_RegisterServerHelloExtensionSender(ss, ssl_tls13_early_data_xtn, - tls13_ServerSendEarlyDataXtn); + rv = ssl3_RegisterExtensionSender(ss, &ss->xtnData, ssl_tls13_early_data_xtn, + tls13_ServerSendEarlyDataXtn); if (rv != SECSuccess) { return SECFailure; /* Error code set already. */ } @@ -2167,13 +2181,13 @@ tls13_HandleServerKeyShare(sslSocket *ss) PORT_Assert(ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss)); /* This list should have one entry. */ - if (PR_CLIST_IS_EMPTY(&ss->ssl3.hs.remoteKeyShares)) { + if (PR_CLIST_IS_EMPTY(&ss->xtnData.remoteKeyShares)) { FATAL_ERROR(ss, SSL_ERROR_MISSING_KEY_SHARE, missing_extension); return SECFailure; } - entry = (TLS13KeyShareEntry *)PR_NEXT_LINK(&ss->ssl3.hs.remoteKeyShares); - PORT_Assert(PR_NEXT_LINK(&entry->link) == &ss->ssl3.hs.remoteKeyShares); + entry = (TLS13KeyShareEntry *)PR_NEXT_LINK(&ss->xtnData.remoteKeyShares); + PORT_Assert(PR_NEXT_LINK(&entry->link) == &ss->xtnData.remoteKeyShares); PORT_Assert(ssl_NamedGroupEnabled(ss, entry->group)); @@ -2869,19 +2883,28 @@ tls13_HandleEncryptedExtensions(sslSocket *ss, SSL3Opaque *b, PRUint32 length) /* If we are doing 0-RTT, then we already have an NPN value. Stash * it for comparison. */ if (ss->ssl3.hs.zeroRttState == ssl_0rtt_sent && - ss->ssl3.nextProtoState == SSL_NEXT_PROTO_EARLY_VALUE) { - oldNpn = ss->ssl3.nextProto; - ss->ssl3.nextProto.data = NULL; - ss->ssl3.nextProtoState = SSL_NEXT_PROTO_NO_SUPPORT; + ss->xtnData.nextProtoState == SSL_NEXT_PROTO_EARLY_VALUE) { + oldNpn = ss->xtnData.nextProto; + ss->xtnData.nextProto.data = NULL; + ss->xtnData.nextProtoState = SSL_NEXT_PROTO_NO_SUPPORT; } rv = ssl3_HandleExtensions(ss, &b, &length, encrypted_extensions); if (rv != SECSuccess) { return SECFailure; /* Error code set below */ } - if (ss->ssl3.hs.zeroRttState == ssl_0rtt_accepted) { + /* We can only get here if we offered 0-RTT. */ + if (ssl3_ExtensionNegotiated(ss, ssl_tls13_early_data_xtn)) { + PORT_Assert(ss->ssl3.hs.zeroRttState == ssl_0rtt_sent); + if (!ss->statelessResume) { + /* Illegal to accept 0-RTT without also accepting PSK. */ + FATAL_ERROR(ss, SSL_ERROR_RX_MALFORMED_ENCRYPTED_EXTENSIONS, + illegal_parameter); + } + ss->ssl3.hs.zeroRttState = ssl_0rtt_accepted; + /* Check that the server negotiated the same ALPN (if any). */ - if (SECITEM_CompareItem(&oldNpn, &ss->ssl3.nextProto)) { + if (SECITEM_CompareItem(&oldNpn, &ss->xtnData.nextProto)) { SECITEM_FreeItem(&oldNpn, PR_FALSE); FATAL_ERROR(ss, SSL_ERROR_NEXT_PROTOCOL_DATA_INVALID, illegal_parameter); @@ -4075,7 +4098,7 @@ tls13_UnprotectRecord(sslSocket *ss, SSL3Ciphertext *cText, sslBuffer *plaintext * Called from tls13_ClientSendEarlyDataXtn(). */ PRBool -tls13_ClientAllow0Rtt(sslSocket *ss, const sslSessionID *sid) +tls13_ClientAllow0Rtt(const sslSocket *ss, const sslSessionID *sid) { if (sid->version < SSL_LIBRARY_VERSION_TLS_1_3) return PR_FALSE; @@ -4096,11 +4119,12 @@ tls13_MaybeDo0RTTHandshake(sslSocket *ss) SECStatus rv; int bufferLen = ss->ssl3.hs.messages.len; - /* Don't do anything if this is the second ClientHello or we decided not to - * do 0-RTT (which means that there is no early_data extension). */ - if (ss->ssl3.hs.zeroRttState != ssl_0rtt_sent) { + /* Don't do anything if there is no early_data xtn, which means we're + * not doing early data. */ + if (!ssl3_ClientExtensionAdvertised(ss, ssl_tls13_early_data_xtn)) { return SECSuccess; } + ss->ssl3.hs.zeroRttState = ssl_0rtt_sent; SSL_TRC(3, ("%d: TLS13[%d]: in 0-RTT mode", SSL_GETPID(), ss->fd)); @@ -4113,8 +4137,8 @@ tls13_MaybeDo0RTTHandshake(sslSocket *ss) /* Set the ALPN data as if it was negotiated. We check in the ServerHello * handler that the server negotiates the same value. */ if (ss->sec.ci.sid->u.ssl3.alpnSelection.len) { - ss->ssl3.nextProtoState = SSL_NEXT_PROTO_EARLY_VALUE; - rv = SECITEM_CopyItem(NULL, &ss->ssl3.nextProto, + ss->xtnData.nextProtoState = SSL_NEXT_PROTO_EARLY_VALUE; + rv = SECITEM_CopyItem(NULL, &ss->xtnData.nextProto, &ss->sec.ci.sid->u.ssl3.alpnSelection); if (rv != SECSuccess) return rv; diff --git a/lib/ssl/tls13con.h b/lib/ssl/tls13con.h index 91420ada01..9dcabe01b1 100644 --- a/lib/ssl/tls13con.h +++ b/lib/ssl/tls13con.h @@ -69,7 +69,7 @@ SECStatus tls13_ProtectRecord(sslSocket *ss, PRInt32 tls13_Read0RttData(sslSocket *ss, void *buf, PRInt32 len); SECStatus tls13_HandleEndOfEarlyData(sslSocket *ss); SECStatus tls13_HandleEarlyApplicationData(sslSocket *ss, sslBuffer *origBuf); -PRBool tls13_ClientAllow0Rtt(sslSocket *ss, const sslSessionID *sid); +PRBool tls13_ClientAllow0Rtt(const sslSocket *ss, const sslSessionID *sid); PRUint16 tls13_EncodeDraftVersion(SSL3ProtocolVersion version); PRUint16 tls13_DecodeDraftVersion(PRUint16 version); SECStatus tls13_NegotiateVersion(sslSocket *ss, diff --git a/lib/ssl/tls13exthandle.c b/lib/ssl/tls13exthandle.c index 570be7b3a5..08ea6b40c5 100644 --- a/lib/ssl/tls13exthandle.c +++ b/lib/ssl/tls13exthandle.c @@ -10,12 +10,14 @@ #include "sslproto.h" #include "sslimpl.h" #include "pk11pub.h" +#include "ssl3ext.h" #include "ssl3exthandle.h" #include "tls13exthandle.h" PRInt32 tls13_ServerSendStatusRequestXtn( - sslSocket *ss, + const sslSocket *ss, + TLSExtensionData *xtnData, PRBool append, PRUint32 maxBytes) { @@ -38,19 +40,19 @@ tls13_ServerSendStatusRequestXtn( } if (append) { /* extension_type */ - rv = ssl3_AppendHandshakeNumber(ss, ssl_cert_status_xtn, 2); + rv = ssl3_ExtAppendHandshakeNumber(ss, ssl_cert_status_xtn, 2); if (rv != SECSuccess) return -1; /* length of extension_data */ - rv = ssl3_AppendHandshakeNumber(ss, extension_length - 4, 2); + rv = ssl3_ExtAppendHandshakeNumber(ss, extension_length - 4, 2); if (rv != SECSuccess) return -1; /* status_type == ocsp */ - rv = ssl3_AppendHandshakeNumber(ss, 1 /*ocsp*/, 1); + rv = ssl3_ExtAppendHandshakeNumber(ss, 1 /*ocsp*/, 1); if (rv != SECSuccess) return rv; /* err set by AppendHandshake. */ /* opaque OCSPResponse<1..2^24-1> */ - rv = ssl3_AppendHandshakeVariable(ss, item->data, item->len, 3); + rv = ssl3_ExtAppendHandshakeVariable(ss, item->data, item->len, 3); if (rv != SECSuccess) return rv; /* err set by AppendHandshake. */ } @@ -84,7 +86,7 @@ tls13_ServerSendStatusRequestXtn( * * opaque point <1..2^8-1>; */ -PRUint32 +static PRUint32 tls13_SizeOfKeyShareEntry(const SECKEYPublicKey *pubKey) { /* Size = NamedGroup(2) + length(2) + opaque share */ @@ -99,8 +101,8 @@ tls13_SizeOfKeyShareEntry(const SECKEYPublicKey *pubKey) return 0; } -PRUint32 -tls13_SizeOfClientKeyShareExtension(sslSocket *ss) +static PRUint32 +tls13_SizeOfClientKeyShareExtension(const sslSocket *ss) { PRCList *cursor; /* Size is: extension(2) + extension_len(2) + client_shares(2) */ @@ -114,17 +116,17 @@ tls13_SizeOfClientKeyShareExtension(sslSocket *ss) return size; } -SECStatus -tls13_EncodeKeyShareEntry(sslSocket *ss, const sslEphemeralKeyPair *keyPair) +static SECStatus +tls13_EncodeKeyShareEntry(const sslSocket *ss, const sslEphemeralKeyPair *keyPair) { SECStatus rv; SECKEYPublicKey *pubKey = keyPair->keys->pubKey; unsigned int size = tls13_SizeOfKeyShareEntry(pubKey); - rv = ssl3_AppendHandshakeNumber(ss, keyPair->group->name, 2); + rv = ssl3_ExtAppendHandshakeNumber(ss, keyPair->group->name, 2); if (rv != SECSuccess) return rv; - rv = ssl3_AppendHandshakeNumber(ss, size - 4, 2); + rv = ssl3_ExtAppendHandshakeNumber(ss, size - 4, 2); if (rv != SECSuccess) return rv; @@ -145,7 +147,7 @@ tls13_EncodeKeyShareEntry(sslSocket *ss, const sslEphemeralKeyPair *keyPair) } PRInt32 -tls13_ClientSendKeyShareXtn(sslSocket *ss, PRBool append, +tls13_ClientSendKeyShareXtn(const sslSocket *ss, TLSExtensionData *xtnData, PRBool append, PRUint32 maxBytes) { PRUint32 extension_length; @@ -169,17 +171,17 @@ tls13_ClientSendKeyShareXtn(sslSocket *ss, PRBool append, SECStatus rv; PRCList *cursor; - rv = ssl3_AppendHandshakeNumber(ss, ssl_tls13_key_share_xtn, 2); + rv = ssl3_ExtAppendHandshakeNumber(ss, ssl_tls13_key_share_xtn, 2); if (rv != SECSuccess) goto loser; /* The extension length */ - rv = ssl3_AppendHandshakeNumber(ss, extension_length - 4, 2); + rv = ssl3_ExtAppendHandshakeNumber(ss, extension_length - 4, 2); if (rv != SECSuccess) goto loser; /* The length of KeyShares */ - rv = ssl3_AppendHandshakeNumber(ss, extension_length - 6, 2); + rv = ssl3_ExtAppendHandshakeNumber(ss, extension_length - 6, 2); if (rv != SECSuccess) goto loser; @@ -192,7 +194,7 @@ tls13_ClientSendKeyShareXtn(sslSocket *ss, PRBool append, goto loser; } - ss->xtnData.advertised[ss->xtnData.numAdvertised++] = + xtnData->advertised[xtnData->numAdvertised++] = ssl_tls13_key_share_xtn; } @@ -202,8 +204,8 @@ tls13_ClientSendKeyShareXtn(sslSocket *ss, PRBool append, return -1; } -SECStatus -tls13_HandleKeyShareEntry(sslSocket *ss, SECItem *data) +static SECStatus +tls13_HandleKeyShareEntry(const sslSocket *ss, TLSExtensionData *xtnData, SECItem *data) { SECStatus rv; PRInt32 group; @@ -211,14 +213,14 @@ tls13_HandleKeyShareEntry(sslSocket *ss, SECItem *data) TLS13KeyShareEntry *ks = NULL; SECItem share = { siBuffer, NULL, 0 }; - group = ssl3_ConsumeHandshakeNumber(ss, 2, &data->data, &data->len); + group = ssl3_ExtConsumeHandshakeNumber(ss, 2, &data->data, &data->len); if (group < 0) { PORT_SetError(SSL_ERROR_RX_MALFORMED_KEY_SHARE); goto loser; } groupDef = ssl_LookupNamedGroup(group); - rv = ssl3_ConsumeHandshakeVariable(ss, &share, 2, &data->data, - &data->len); + rv = ssl3_ExtConsumeHandshakeVariable(ss, &share, 2, &data->data, + &data->len); if (rv != SECSuccess) { goto loser; } @@ -236,7 +238,7 @@ tls13_HandleKeyShareEntry(sslSocket *ss, SECItem *data) if (rv != SECSuccess) goto loser; - PR_APPEND_LINK(&ks->link, &ss->ssl3.hs.remoteKeyShares); + PR_APPEND_LINK(&ks->link, &xtnData->remoteKeyShares); return SECSuccess; loser: @@ -244,14 +246,14 @@ tls13_HandleKeyShareEntry(sslSocket *ss, SECItem *data) tls13_DestroyKeyShareEntry(ks); return SECFailure; } - /* Handle an incoming KeyShare extension at the client and copy to - * |ss->ssl3.hs.remoteKeyShares| for future use. The key + * |xtnData->remoteKeyShares| for future use. The key * share is processed in tls13_HandleServerKeyShare(). */ SECStatus -tls13_ClientHandleKeyShareXtn(sslSocket *ss, PRUint16 ex_type, SECItem *data) +tls13_ClientHandleKeyShareXtn(const sslSocket *ss, TLSExtensionData *xtnData, PRUint16 ex_type, SECItem *data) { SECStatus rv; + PORT_Assert(PR_CLIST_IS_EMPTY(&xtnData->remoteKeyShares)); PORT_Assert(!ss->sec.isServer); if (ss->version < SSL_LIBRARY_VERSION_TLS_1_3) { @@ -265,7 +267,7 @@ tls13_ClientHandleKeyShareXtn(sslSocket *ss, PRUint16 ex_type, SECItem *data) SSL_TRC(3, ("%d: SSL3[%d]: handle key_share extension", SSL_GETPID(), ss->fd)); - rv = tls13_HandleKeyShareEntry(ss, data); + rv = tls13_HandleKeyShareEntry(ss, xtnData, data); if (rv != SECSuccess) { PORT_SetError(SSL_ERROR_RX_MALFORMED_KEY_SHARE); return SECFailure; @@ -280,7 +282,7 @@ tls13_ClientHandleKeyShareXtn(sslSocket *ss, PRUint16 ex_type, SECItem *data) } SECStatus -tls13_ClientHandleKeyShareXtnHrr(sslSocket *ss, PRUint16 ex_type, SECItem *data) +tls13_ClientHandleKeyShareXtnHrr(const sslSocket *ss, TLSExtensionData *xtnData, PRUint16 ex_type, SECItem *data) { SECStatus rv; PRInt32 tmp; @@ -292,12 +294,12 @@ tls13_ClientHandleKeyShareXtnHrr(sslSocket *ss, PRUint16 ex_type, SECItem *data) 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); + tmp = ssl3_ExtConsumeHandshakeNumber(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); + ssl3_ExtSendAlert(ss, alert_fatal, decode_error); PORT_SetError(SSL_ERROR_RX_MALFORMED_HELLO_RETRY_REQUEST); return SECFailure; } @@ -306,15 +308,15 @@ tls13_ClientHandleKeyShareXtnHrr(sslSocket *ss, PRUint16 ex_type, SECItem *data) /* 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); + ssl_HaveEphemeralKeyPair(ss, group)) { + ssl3_ExtSendAlert(ss, alert_fatal, illegal_parameter); PORT_SetError(SSL_ERROR_RX_MALFORMED_HELLO_RETRY_REQUEST); return SECFailure; } - rv = tls13_CreateKeyShare(ss, group); + rv = tls13_CreateKeyShare(CONST_CAST(sslSocket, ss), group); if (rv != SECSuccess) { - (void)SSL3_SendAlert(ss, alert_fatal, internal_error); + ssl3_ExtSendAlert(ss, alert_fatal, internal_error); PORT_SetError(SEC_ERROR_KEYGEN_FAIL); return SECFailure; } @@ -323,15 +325,17 @@ tls13_ClientHandleKeyShareXtnHrr(sslSocket *ss, PRUint16 ex_type, SECItem *data) } /* Handle an incoming KeyShare extension at the server and copy to - * |ss->ssl3.hs.remoteKeyShares| for future use. The key + * |xtnData->remoteKeyShares| for future use. The key * share is processed in tls13_HandleClientKeyShare(). */ SECStatus -tls13_ServerHandleKeyShareXtn(sslSocket *ss, PRUint16 ex_type, SECItem *data) +tls13_ServerHandleKeyShareXtn(const sslSocket *ss, TLSExtensionData *xtnData, PRUint16 ex_type, SECItem *data) { SECStatus rv; PRInt32 length; PORT_Assert(ss->sec.isServer); + PORT_Assert(PR_CLIST_IS_EMPTY(&xtnData->remoteKeyShares)); + if (ss->version < SSL_LIBRARY_VERSION_TLS_1_3) { return SECSuccess; } @@ -341,8 +345,8 @@ tls13_ServerHandleKeyShareXtn(sslSocket *ss, PRUint16 ex_type, SECItem *data) /* Redundant length because of TLS encoding (this vector consumes * the entire extension.) */ - length = ssl3_ConsumeHandshakeNumber(ss, 2, &data->data, - &data->len); + length = ssl3_ExtConsumeHandshakeNumber(ss, 2, &data->data, + &data->len); if (length < 0) goto loser; if (length != data->len) { @@ -352,19 +356,19 @@ tls13_ServerHandleKeyShareXtn(sslSocket *ss, PRUint16 ex_type, SECItem *data) } while (data->len) { - rv = tls13_HandleKeyShareEntry(ss, data); + rv = tls13_HandleKeyShareEntry(ss, xtnData, data); if (rv != SECSuccess) goto loser; } return SECSuccess; loser: - tls13_DestroyKeyShares(&ss->ssl3.hs.remoteKeyShares); + tls13_DestroyKeyShares(&xtnData->remoteKeyShares); return SECFailure; } PRInt32 -tls13_ServerSendKeyShareXtn(sslSocket *ss, PRBool append, +tls13_ServerSendKeyShareXtn(const sslSocket *ss, TLSExtensionData *xtnData, PRBool append, PRUint32 maxBytes) { PRUint32 extension_length; @@ -387,11 +391,11 @@ tls13_ServerSendKeyShareXtn(sslSocket *ss, PRBool append, } if (append) { - rv = ssl3_AppendHandshakeNumber(ss, ssl_tls13_key_share_xtn, 2); + rv = ssl3_ExtAppendHandshakeNumber(ss, ssl_tls13_key_share_xtn, 2); if (rv != SECSuccess) goto loser; - rv = ssl3_AppendHandshakeNumber(ss, entry_length, 2); + rv = ssl3_ExtAppendHandshakeNumber(ss, entry_length, 2); if (rv != SECSuccess) goto loser; @@ -427,7 +431,7 @@ tls13_ServerSendKeyShareXtn(sslSocket *ss, PRBool append, * really a ticket label and there wll be at most one. */ PRInt32 -tls13_ClientSendPreSharedKeyXtn(sslSocket *ss, +tls13_ClientSendPreSharedKeyXtn(const sslSocket *ss, TLSExtensionData *xtnData, PRBool append, PRUint32 maxBytes) { @@ -460,44 +464,44 @@ tls13_ClientSendPreSharedKeyXtn(sslSocket *ss, if (append) { SECStatus rv; /* extension_type */ - rv = ssl3_AppendHandshakeNumber(ss, ssl_tls13_pre_shared_key_xtn, 2); + rv = ssl3_ExtAppendHandshakeNumber(ss, ssl_tls13_pre_shared_key_xtn, 2); if (rv != SECSuccess) goto loser; - rv = ssl3_AppendHandshakeNumber(ss, extension_length - 4, 2); + rv = ssl3_ExtAppendHandshakeNumber(ss, extension_length - 4, 2); if (rv != SECSuccess) goto loser; - rv = ssl3_AppendHandshakeNumber(ss, extension_length - 6, 2); + rv = ssl3_ExtAppendHandshakeNumber(ss, extension_length - 6, 2); if (rv != SECSuccess) goto loser; - rv = ssl3_AppendHandshakeVariable(ss, ke_modes, ke_modes_len, 1); + rv = ssl3_ExtAppendHandshakeVariable(ss, ke_modes, ke_modes_len, 1); if (rv != SECSuccess) goto loser; - rv = ssl3_AppendHandshakeVariable(ss, auth_modes, auth_modes_len, 1); + rv = ssl3_ExtAppendHandshakeVariable(ss, auth_modes, auth_modes_len, 1); if (rv != SECSuccess) goto loser; - rv = ssl3_AppendHandshakeVariable(ss, session_ticket->ticket.data, - session_ticket->ticket.len, 2); + rv = ssl3_ExtAppendHandshakeVariable(ss, session_ticket->ticket.data, + session_ticket->ticket.len, 2); PRINT_BUF(50, (ss, "Sending PreSharedKey value", session_ticket->ticket.data, session_ticket->ticket.len)); - ss->xtnData.sentSessionTicketInClientHello = PR_TRUE; + xtnData->sentSessionTicketInClientHello = PR_TRUE; if (rv != SECSuccess) goto loser; - ss->xtnData.advertised[ss->xtnData.numAdvertised++] = + xtnData->advertised[xtnData->numAdvertised++] = ssl_tls13_pre_shared_key_xtn; } return extension_length; loser: - ss->xtnData.ticketTimestampVerified = PR_FALSE; + xtnData->ticketTimestampVerified = PR_FALSE; return -1; } /* Handle a TLS 1.3 PreSharedKey Extension. We only accept PSKs * that contain session tickets. */ SECStatus -tls13_ServerHandlePreSharedKeyXtn(sslSocket *ss, PRUint16 ex_type, +tls13_ServerHandlePreSharedKeyXtn(const sslSocket *ss, TLSExtensionData *xtnData, PRUint16 ex_type, SECItem *data) { PRInt32 len; @@ -512,7 +516,7 @@ tls13_ServerHandlePreSharedKeyXtn(sslSocket *ss, PRUint16 ex_type, return SECSuccess; } - len = ssl3_ConsumeHandshakeNumber(ss, 2, &data->data, &data->len); + len = ssl3_ExtConsumeHandshakeNumber(ss, 2, &data->data, &data->len); if (len < 0) return SECFailure; @@ -526,22 +530,22 @@ tls13_ServerHandlePreSharedKeyXtn(sslSocket *ss, PRUint16 ex_type, /* IMPORTANT: We aren't copying these values, just setting pointers. * They will only be valid as long as the ClientHello is in memory. */ - rv = ssl3_ConsumeHandshakeVariable(ss, &ss->xtnData.psk_ke_modes, 1, - &data->data, &data->len); + rv = ssl3_ExtConsumeHandshakeVariable(ss, &xtnData->psk_ke_modes, 1, + &data->data, &data->len); if (rv != SECSuccess) return rv; - if (!ss->xtnData.psk_ke_modes.len) { + if (!xtnData->psk_ke_modes.len) { goto alert_loser; } - rv = ssl3_ConsumeHandshakeVariable(ss, &ss->xtnData.psk_auth_modes, 1, - &data->data, &data->len); + rv = ssl3_ExtConsumeHandshakeVariable(ss, &xtnData->psk_auth_modes, 1, + &data->data, &data->len); if (rv != SECSuccess) return rv; - if (!ss->xtnData.psk_auth_modes.len) { + if (!xtnData->psk_auth_modes.len) { goto alert_loser; } - rv = ssl3_ConsumeHandshakeVariable(ss, &label, 2, - &data->data, &data->len); + rv = ssl3_ExtConsumeHandshakeVariable(ss, &label, 2, + &data->data, &data->len); if (rv != SECSuccess) return rv; if (!label.len) { @@ -553,7 +557,8 @@ tls13_ServerHandlePreSharedKeyXtn(sslSocket *ss, PRUint16 ex_type, PRINT_BUF(50, (ss, "Handling PreSharedKey value", label.data, label.len)); - rv = ssl3_ProcessSessionTicketCommon(ss, &label); + rv = ssl3_ProcessSessionTicketCommon(CONST_CAST(sslSocket, ss), + &label); /* This only happens if we have an internal error, not * a malformed ticket. Bogus tickets just don't resume * and return SECSuccess. */ @@ -564,18 +569,18 @@ tls13_ServerHandlePreSharedKeyXtn(sslSocket *ss, PRUint16 ex_type, /* Keep track of negotiated extensions. Note that this does not * mean we are resuming. */ - ss->xtnData.negotiated[ss->xtnData.numNegotiated++] = ex_type; + xtnData->negotiated[xtnData->numNegotiated++] = ex_type; return SECSuccess; alert_loser: - (void)SSL3_SendAlert(ss, alert_fatal, illegal_parameter); + ssl3_ExtSendAlert(ss, alert_fatal, illegal_parameter); PORT_SetError(SSL_ERROR_MALFORMED_PRE_SHARED_KEY); return SECFailure; } PRInt32 -tls13_ServerSendPreSharedKeyXtn(sslSocket *ss, +tls13_ServerSendPreSharedKeyXtn(const sslSocket *ss, TLSExtensionData *xtnData, PRBool append, PRUint32 maxBytes) { @@ -589,17 +594,17 @@ tls13_ServerSendPreSharedKeyXtn(sslSocket *ss, } if (append) { - rv = ssl3_AppendHandshakeNumber(ss, ssl_tls13_pre_shared_key_xtn, 2); + rv = ssl3_ExtAppendHandshakeNumber(ss, ssl_tls13_pre_shared_key_xtn, 2); if (rv != SECSuccess) return -1; - rv = ssl3_AppendHandshakeNumber(ss, 2, 2); + rv = ssl3_ExtAppendHandshakeNumber(ss, 2, 2); if (rv != SECSuccess) return -1; /* We only process the first session ticket the client sends, * so the index is always 0. */ - rv = ssl3_AppendHandshakeNumber(ss, 0, 2); + rv = ssl3_ExtAppendHandshakeNumber(ss, 0, 2); if (rv != SECSuccess) return -1; } @@ -610,7 +615,7 @@ tls13_ServerSendPreSharedKeyXtn(sslSocket *ss, /* Handle a TLS 1.3 PreSharedKey Extension. We only accept PSKs * that contain session tickets. */ SECStatus -tls13_ClientHandlePreSharedKeyXtn(sslSocket *ss, PRUint16 ex_type, +tls13_ClientHandlePreSharedKeyXtn(const sslSocket *ss, TLSExtensionData *xtnData, PRUint16 ex_type, SECItem *data) { PRInt32 index; @@ -623,7 +628,7 @@ tls13_ClientHandlePreSharedKeyXtn(sslSocket *ss, PRUint16 ex_type, return SECSuccess; } - index = ssl3_ConsumeHandshakeNumber(ss, 2, &data->data, &data->len); + index = ssl3_ExtConsumeHandshakeNumber(ss, 2, &data->data, &data->len); if (index < 0) return SECFailure; @@ -640,7 +645,7 @@ tls13_ClientHandlePreSharedKeyXtn(sslSocket *ss, PRUint16 ex_type, } /* Keep track of negotiated extensions. */ - ss->xtnData.negotiated[ss->xtnData.numNegotiated++] = ex_type; + xtnData->negotiated[xtnData->numNegotiated++] = ex_type; return SECSuccess; } @@ -657,7 +662,7 @@ tls13_ClientHandlePreSharedKeyXtn(sslSocket *ss, PRUint16 ex_type, * } EarlyDataIndication; */ PRInt32 -tls13_ClientSendEarlyDataXtn(sslSocket *ss, +tls13_ClientSendEarlyDataXtn(const sslSocket *ss, TLSExtensionData *xtnData, PRBool append, PRUint32 maxBytes) { @@ -680,11 +685,11 @@ tls13_ClientSendEarlyDataXtn(sslSocket *ss, if (append) { PRUint32 age; - rv = ssl3_AppendHandshakeNumber(ss, ssl_tls13_early_data_xtn, 2); + rv = ssl3_ExtAppendHandshakeNumber(ss, ssl_tls13_early_data_xtn, 2); if (rv != SECSuccess) return -1; - rv = ssl3_AppendHandshakeNumber(ss, extension_length - 4, 2); + rv = ssl3_ExtAppendHandshakeNumber(ss, extension_length - 4, 2); if (rv != SECSuccess) return -1; @@ -692,20 +697,19 @@ tls13_ClientSendEarlyDataXtn(sslSocket *ss, age = ssl_Time() - session_ticket->received_timestamp; age += session_ticket->ticket_age_add; - rv = ssl3_AppendHandshakeNumber(ss, age, 4); + rv = ssl3_ExtAppendHandshakeNumber(ss, age, 4); if (rv != SECSuccess) return -1; } - ss->ssl3.hs.zeroRttState = ssl_0rtt_sent; - ss->xtnData.advertised[ss->xtnData.numAdvertised++] = + xtnData->advertised[xtnData->numAdvertised++] = ssl_tls13_early_data_xtn; return extension_length; } SECStatus -tls13_ServerHandleEarlyDataXtn(sslSocket *ss, PRUint16 ex_type, +tls13_ServerHandleEarlyDataXtn(const sslSocket *ss, TLSExtensionData *xtnData, PRUint16 ex_type, SECItem *data) { PRUint32 obfuscated_ticket_age; @@ -720,8 +724,8 @@ tls13_ServerHandleEarlyDataXtn(sslSocket *ss, PRUint16 ex_type, } /* Obfuscated ticket age. Ignore. Bug 1295163. */ - rv = ssl3_ConsumeHandshake(ss, &obfuscated_ticket_age, 4, - &data->data, &data->len); + rv = ssl3_ExtConsumeHandshake(ss, &obfuscated_ticket_age, 4, + &data->data, &data->len); if (rv != SECSuccess) { return SECFailure; } @@ -731,26 +735,14 @@ tls13_ServerHandleEarlyDataXtn(sslSocket *ss, PRUint16 ex_type, return SECFailure; } - if (IS_DTLS(ss)) { - /* Save the null spec, which we should be currently reading. We will - * use this when 0-RTT sending is over. */ - ssl_GetSpecReadLock(ss); - ss->ssl3.hs.nullSpec = ss->ssl3.crSpec; - tls13_CipherSpecAddRef(ss->ssl3.hs.nullSpec); - PORT_Assert(ss->ssl3.hs.nullSpec->cipher_def->cipher == cipher_null); - ssl_ReleaseSpecReadLock(ss); - } - - ss->ssl3.hs.zeroRttState = ssl_0rtt_sent; - - ss->xtnData.negotiated[ss->xtnData.numNegotiated++] = ex_type; + xtnData->negotiated[xtnData->numNegotiated++] = ex_type; return SECSuccess; } /* This is only registered if we are sending it. */ -SECStatus -tls13_ServerSendEarlyDataXtn(sslSocket *ss, +PRInt32 +tls13_ServerSendEarlyDataXtn(const sslSocket *ss, TLSExtensionData *xtnData, PRBool append, PRUint32 maxBytes) { @@ -766,11 +758,11 @@ tls13_ServerSendEarlyDataXtn(sslSocket *ss, if (append) { SECStatus rv; - rv = ssl3_AppendHandshakeNumber(ss, ssl_tls13_early_data_xtn, 2); + rv = ssl3_ExtAppendHandshakeNumber(ss, ssl_tls13_early_data_xtn, 2); if (rv != SECSuccess) return -1; - rv = ssl3_AppendHandshakeNumber(ss, 0, 2); + rv = ssl3_ExtAppendHandshakeNumber(ss, 0, 2); if (rv != SECSuccess) return -1; } @@ -780,7 +772,7 @@ tls13_ServerSendEarlyDataXtn(sslSocket *ss, /* This will only be called if we also offered the extension. */ SECStatus -tls13_ClientHandleEarlyDataXtn(sslSocket *ss, PRUint16 ex_type, +tls13_ClientHandleEarlyDataXtn(const sslSocket *ss, TLSExtensionData *xtnData, PRUint16 ex_type, SECItem *data) { SSL_TRC(3, ("%d: TLS13[%d]: handle early_data extension", @@ -798,14 +790,13 @@ tls13_ClientHandleEarlyDataXtn(sslSocket *ss, PRUint16 ex_type, } /* Keep track of negotiated extensions. */ - ss->xtnData.negotiated[ss->xtnData.numNegotiated++] = ex_type; - ss->ssl3.hs.zeroRttState = ssl_0rtt_accepted; + xtnData->negotiated[xtnData->numNegotiated++] = ex_type; return SECSuccess; } SECStatus -tls13_ClientHandleTicketEarlyDataInfoXtn(sslSocket *ss, PRUint16 ex_type, +tls13_ClientHandleTicketEarlyDataInfoXtn(const sslSocket *ss, TLSExtensionData *xtnData, PRUint16 ex_type, SECItem *data) { PRUint32 utmp; @@ -820,8 +811,8 @@ tls13_ClientHandleTicketEarlyDataInfoXtn(sslSocket *ss, PRUint16 ex_type, return SECFailure; } - rv = ssl3_ConsumeHandshake(ss, &utmp, sizeof(utmp), - &data->data, &data->len); + rv = ssl3_ExtConsumeHandshake(ss, &utmp, sizeof(utmp), + &data->data, &data->len); if (rv != SECSuccess) { PORT_SetError(SSL_ERROR_RX_MALFORMED_NEW_SESSION_TICKET); return SECFailure; @@ -831,15 +822,15 @@ tls13_ClientHandleTicketEarlyDataInfoXtn(sslSocket *ss, PRUint16 ex_type, return SECFailure; } - ss->xtnData.ticket_age_add_found = PR_TRUE; - ss->xtnData.ticket_age_add = PR_ntohl(utmp); + xtnData->ticket_age_add_found = PR_TRUE; + xtnData->ticket_age_add = PR_ntohl(utmp); return SECSuccess; } /* This is only registered if we are sending it. */ -SECStatus -tls13_ServerSendSigAlgsXtn(sslSocket *ss, +PRInt32 +tls13_ServerSendSigAlgsXtn(const sslSocket *ss, TLSExtensionData *xtnData, PRBool append, PRUint32 maxBytes) { @@ -853,11 +844,11 @@ tls13_ServerSendSigAlgsXtn(sslSocket *ss, if (append) { SECStatus rv; - rv = ssl3_AppendHandshakeNumber(ss, ssl_signature_algorithms_xtn, 2); + rv = ssl3_ExtAppendHandshakeNumber(ss, ssl_signature_algorithms_xtn, 2); if (rv != SECSuccess) return -1; - rv = ssl3_AppendHandshakeNumber(ss, 0, 2); + rv = ssl3_ExtAppendHandshakeNumber(ss, 0, 2); if (rv != SECSuccess) return -1; } @@ -867,7 +858,7 @@ tls13_ServerSendSigAlgsXtn(sslSocket *ss, /* This will only be called if we also offered the extension. */ SECStatus -tls13_ClientHandleSigAlgsXtn(sslSocket *ss, PRUint16 ex_type, +tls13_ClientHandleSigAlgsXtn(const sslSocket *ss, TLSExtensionData *xtnData, PRUint16 ex_type, SECItem *data) { SSL_TRC(3, ("%d: TLS13[%d]: handle signature_algorithms extension", @@ -885,7 +876,7 @@ tls13_ClientHandleSigAlgsXtn(sslSocket *ss, PRUint16 ex_type, } /* Keep track of negotiated extensions. */ - ss->xtnData.negotiated[ss->xtnData.numNegotiated++] = ex_type; + xtnData->negotiated[xtnData->numNegotiated++] = ex_type; return SECSuccess; } @@ -896,7 +887,7 @@ tls13_ClientHandleSigAlgsXtn(sslSocket *ss, PRUint16 ex_type, * } SupportedVersions; */ PRInt32 -tls13_ClientSendSupportedVersionsXtn(sslSocket *ss, PRBool append, +tls13_ClientSendSupportedVersionsXtn(const sslSocket *ss, TLSExtensionData *xtnData, PRBool append, PRUint32 maxBytes) { PRInt32 extensions_len; @@ -921,20 +912,20 @@ tls13_ClientSendSupportedVersionsXtn(sslSocket *ss, PRBool append, } if (append) { - rv = ssl3_AppendHandshakeNumber(ss, ssl_tls13_supported_versions_xtn, 2); + rv = ssl3_ExtAppendHandshakeNumber(ss, ssl_tls13_supported_versions_xtn, 2); if (rv != SECSuccess) return -1; - rv = ssl3_AppendHandshakeNumber(ss, extensions_len - 4, 2); + rv = ssl3_ExtAppendHandshakeNumber(ss, extensions_len - 4, 2); if (rv != SECSuccess) return -1; - rv = ssl3_AppendHandshakeNumber(ss, extensions_len - 5, 1); + rv = ssl3_ExtAppendHandshakeNumber(ss, extensions_len - 5, 1); if (rv != SECSuccess) return -1; for (version = ss->vrange.max; version >= ss->vrange.min; --version) { - rv = ssl3_AppendHandshakeNumber( + rv = ssl3_ExtAppendHandshakeNumber( ss, tls13_EncodeDraftVersion(version), 2); if (rv != SECSuccess) return -1; @@ -950,7 +941,7 @@ tls13_ClientSendSupportedVersionsXtn(sslSocket *ss, PRBool append, * } Cookie; */ SECStatus -tls13_ClientHandleHrrCookie(sslSocket *ss, PRUint16 ex_type, SECItem *data) +tls13_ClientHandleHrrCookie(const sslSocket *ss, TLSExtensionData *xtnData, PRUint16 ex_type, SECItem *data) { SECStatus rv; @@ -960,14 +951,15 @@ tls13_ClientHandleHrrCookie(sslSocket *ss, PRUint16 ex_type, SECItem *data) PORT_Assert(ss->vrange.max >= SSL_LIBRARY_VERSION_TLS_1_3); /* IMPORTANT: this is only valid while the HelloRetryRequest is still valid. */ - rv = ssl3_ConsumeHandshakeVariable(ss, &ss->ssl3.hs.cookie, 2, - &data->data, &data->len); + rv = ssl3_ExtConsumeHandshakeVariable( + ss, &CONST_CAST(sslSocket, ss)->ssl3.hs.cookie, 2, + &data->data, &data->len); if (rv != SECSuccess) { PORT_SetError(SSL_ERROR_RX_MALFORMED_HELLO_RETRY_REQUEST); return SECFailure; } if (!ss->ssl3.hs.cookie.len || data->len) { - (void)SSL3_SendAlert(ss, alert_fatal, decode_error); + ssl3_ExtSendAlert(ss, alert_fatal, decode_error); PORT_SetError(SSL_ERROR_RX_MALFORMED_HELLO_RETRY_REQUEST); return SECFailure; } @@ -976,7 +968,7 @@ tls13_ClientHandleHrrCookie(sslSocket *ss, PRUint16 ex_type, SECItem *data) } PRInt32 -tls13_ClientSendHrrCookieXtn(sslSocket *ss, PRBool append, PRUint32 maxBytes) +tls13_ClientSendHrrCookieXtn(const sslSocket *ss, TLSExtensionData *xtnData, PRBool append, PRUint32 maxBytes) { PRInt32 extension_len; @@ -996,16 +988,16 @@ tls13_ClientSendHrrCookieXtn(sslSocket *ss, PRBool append, PRUint32 maxBytes) } if (append) { - SECStatus rv = ssl3_AppendHandshakeNumber(ss, ssl_tls13_cookie_xtn, 2); + SECStatus rv = ssl3_ExtAppendHandshakeNumber(ss, ssl_tls13_cookie_xtn, 2); if (rv != SECSuccess) return -1; - rv = ssl3_AppendHandshakeNumber(ss, extension_len - 4, 2); + rv = ssl3_ExtAppendHandshakeNumber(ss, extension_len - 4, 2); if (rv != SECSuccess) return -1; - rv = ssl3_AppendHandshakeVariable(ss, ss->ssl3.hs.cookie.data, - ss->ssl3.hs.cookie.len, 2); + rv = ssl3_ExtAppendHandshakeVariable(ss, ss->ssl3.hs.cookie.data, + ss->ssl3.hs.cookie.len, 2); if (rv != SECSuccess) return -1; } diff --git a/lib/ssl/tls13exthandle.h b/lib/ssl/tls13exthandle.h index c6b6c8dcdf..84149a1652 100644 --- a/lib/ssl/tls13exthandle.h +++ b/lib/ssl/tls13exthandle.h @@ -9,45 +9,58 @@ #ifndef __tls13exthandle_h_ #define __tls13exthandle_h_ -PRInt32 tls13_ServerSendStatusRequestXtn(sslSocket *ss, +PRInt32 tls13_ServerSendStatusRequestXtn(const sslSocket *ss, TLSExtensionData *xtnData, PRBool append, PRUint32 maxBytes); -PRInt32 tls13_ClientSendKeyShareXtn(sslSocket *ss, PRBool append, +PRInt32 tls13_ClientSendKeyShareXtn(const sslSocket *ss, TLSExtensionData *xtnData, PRBool append, PRUint32 maxBytes); -SECStatus tls13_ClientHandleKeyShareXtn(sslSocket *ss, +SECStatus tls13_ClientHandleKeyShareXtn(const sslSocket *ss, TLSExtensionData *xtnData, PRUint16 ex_type, SECItem *data); -SECStatus tls13_ClientHandleKeyShareXtnHrr(sslSocket *ss, +SECStatus tls13_ClientHandleKeyShareXtnHrr(const sslSocket *ss, TLSExtensionData *xtnData, PRUint16 ex_type, SECItem *data); -SECStatus tls13_ServerHandleKeyShareXtn(sslSocket *ss, +SECStatus tls13_ServerHandleKeyShareXtn(const sslSocket *ss, TLSExtensionData *xtnData, PRUint16 ex_type, SECItem *data); -PRInt32 tls13_ClientSendPreSharedKeyXtn(sslSocket *ss, PRBool append, +PRInt32 tls13_ServerSendKeyShareXtn(const sslSocket *ss, + TLSExtensionData *xtnData, + PRBool append, + PRUint32 maxBytes); +PRInt32 tls13_ClientSendPreSharedKeyXtn(const sslSocket *ss, TLSExtensionData *xtnData, PRBool append, PRUint32 maxBytes); -SECStatus tls13_ServerHandlePreSharedKeyXtn(sslSocket *ss, +SECStatus tls13_ServerHandlePreSharedKeyXtn(const sslSocket *ss, TLSExtensionData *xtnData, PRUint16 ex_type, SECItem *data); -SECStatus tls13_ClientHandlePreSharedKeyXtn(sslSocket *ss, +SECStatus tls13_ClientHandlePreSharedKeyXtn(const sslSocket *ss, TLSExtensionData *xtnData, PRUint16 ex_type, SECItem *data); -PRInt32 tls13_ClientSendEarlyDataXtn(sslSocket *ss, +PRInt32 tls13_ServerSendPreSharedKeyXtn(const sslSocket *ss, TLSExtensionData *xtnData, + PRBool append, + PRUint32 maxBytes); +PRInt32 tls13_ClientSendEarlyDataXtn(const sslSocket *ss, TLSExtensionData *xtnData, PRBool append, PRUint32 maxBytes); -SECStatus tls13_ServerHandleEarlyDataXtn(sslSocket *ss, PRUint16 ex_type, +SECStatus tls13_ServerHandleEarlyDataXtn(const sslSocket *ss, TLSExtensionData *xtnData, PRUint16 ex_type, SECItem *data); -SECStatus tls13_ClientHandleEarlyDataXtn(sslSocket *ss, PRUint16 ex_type, +SECStatus tls13_ClientHandleEarlyDataXtn(const sslSocket *ss, TLSExtensionData *xtnData, PRUint16 ex_type, SECItem *data); +PRInt32 tls13_ServerSendEarlyDataXtn(const sslSocket *ss, TLSExtensionData *xtnData, + PRBool append, + PRUint32 maxBytes); SECStatus tls13_ClientHandleTicketEarlyDataInfoXtn( - sslSocket *ss, PRUint16 ex_type, + const sslSocket *ss, TLSExtensionData *xtnData, PRUint16 ex_type, SECItem *data); -SECStatus tls13_ClientHandleSigAlgsXtn(sslSocket *ss, PRUint16 ex_type, +SECStatus tls13_ClientHandleSigAlgsXtn(const sslSocket *ss, TLSExtensionData *xtnData, PRUint16 ex_type, SECItem *data); -PRInt32 tls13_ClientSendSupportedVersionsXtn(sslSocket *ss, +PRInt32 tls13_ServerSendSigAlgsXtn(const sslSocket *ss, TLSExtensionData *xtnData, + PRBool append, + PRUint32 maxBytes); +PRInt32 tls13_ClientSendSupportedVersionsXtn(const sslSocket *ss, TLSExtensionData *xtnData, PRBool append, PRUint32 maxBytes); -SECStatus tls13_ClientHandleHrrCookie(sslSocket *ss, PRUint16 ex_type, +SECStatus tls13_ClientHandleHrrCookie(const sslSocket *ss, TLSExtensionData *xtnData, PRUint16 ex_type, SECItem *data); -PRInt32 tls13_ClientSendHrrCookieXtn(sslSocket *ss, +PRInt32 tls13_ClientSendHrrCookieXtn(const sslSocket *ss, TLSExtensionData *xtnData, PRBool append, PRUint32 maxBytes);