| Index: net/third_party/nss/ssl/ssl3ext.c
|
| diff --git a/net/third_party/nss/ssl/ssl3ext.c b/net/third_party/nss/ssl/ssl3ext.c
|
| index eb3fb70f2805c444317ee87ee55760b36fa31660..3b48c9e0aad3a54ba4d4c6ca556327fac3741c8d 100644
|
| --- a/net/third_party/nss/ssl/ssl3ext.c
|
| +++ b/net/third_party/nss/ssl/ssl3ext.c
|
| @@ -11,8 +11,8 @@
|
| #include "nssrenam.h"
|
| #include "nss.h"
|
| #include "ssl.h"
|
| -#include "sslimpl.h"
|
| #include "sslproto.h"
|
| +#include "sslimpl.h"
|
| #include "pk11pub.h"
|
| #ifdef NO_PKCS11_BYPASS
|
| #include "blapit.h"
|
| @@ -21,42 +21,42 @@
|
| #endif
|
| #include "prinit.h"
|
|
|
| -static unsigned char key_name[SESS_TICKET_KEY_NAME_LEN];
|
| -static PK11SymKey *session_ticket_enc_key_pkcs11 = NULL;
|
| -static PK11SymKey *session_ticket_mac_key_pkcs11 = NULL;
|
| +static unsigned char key_name[SESS_TICKET_KEY_NAME_LEN];
|
| +static PK11SymKey *session_ticket_enc_key_pkcs11 = NULL;
|
| +static PK11SymKey *session_ticket_mac_key_pkcs11 = NULL;
|
|
|
| #ifndef NO_PKCS11_BYPASS
|
| -static unsigned char session_ticket_enc_key[AES_256_KEY_LENGTH];
|
| -static unsigned char session_ticket_mac_key[SHA256_LENGTH];
|
| +static unsigned char session_ticket_enc_key[AES_256_KEY_LENGTH];
|
| +static unsigned char session_ticket_mac_key[SHA256_LENGTH];
|
|
|
| -static PRBool session_ticket_keys_initialized = PR_FALSE;
|
| +static PRBool session_ticket_keys_initialized = PR_FALSE;
|
| #endif
|
| static PRCallOnceType generate_session_keys_once;
|
|
|
| /* forward static function declarations */
|
| static SECStatus ssl3_ParseEncryptedSessionTicket(sslSocket *ss,
|
| - SECItem *data, EncryptedSessionTicket *enc_session_ticket);
|
| + SECItem *data, EncryptedSessionTicket *enc_session_ticket);
|
| static SECStatus ssl3_AppendToItem(SECItem *item, const unsigned char *buf,
|
| - PRUint32 bytes);
|
| + PRUint32 bytes);
|
| static SECStatus ssl3_AppendNumberToItem(SECItem *item, PRUint32 num,
|
| - PRInt32 lenSize);
|
| + PRInt32 lenSize);
|
| static SECStatus ssl3_GetSessionTicketKeysPKCS11(sslSocket *ss,
|
| - PK11SymKey **aes_key, PK11SymKey **mac_key);
|
| + PK11SymKey **aes_key, PK11SymKey **mac_key);
|
| #ifndef NO_PKCS11_BYPASS
|
| static SECStatus ssl3_GetSessionTicketKeys(const unsigned char **aes_key,
|
| - PRUint32 *aes_key_length, const unsigned char **mac_key,
|
| - PRUint32 *mac_key_length);
|
| + PRUint32 *aes_key_length, const unsigned char **mac_key,
|
| + PRUint32 *mac_key_length);
|
| #endif
|
| -static PRInt32 ssl3_SendRenegotiationInfoXtn(sslSocket * ss,
|
| - PRBool append, PRUint32 maxBytes);
|
| +static PRInt32 ssl3_SendRenegotiationInfoXtn(sslSocket *ss,
|
| + PRBool append, PRUint32 maxBytes);
|
| static SECStatus ssl3_HandleRenegotiationInfoXtn(sslSocket *ss,
|
| - PRUint16 ex_type, SECItem *data);
|
| + PRUint16 ex_type, SECItem *data);
|
| static SECStatus ssl3_ClientHandleNextProtoNegoXtn(sslSocket *ss,
|
| - PRUint16 ex_type, SECItem *data);
|
| + PRUint16 ex_type, SECItem *data);
|
| static SECStatus ssl3_ClientHandleAppProtoXtn(sslSocket *ss,
|
| - PRUint16 ex_type, SECItem *data);
|
| + PRUint16 ex_type, SECItem *data);
|
| static SECStatus ssl3_ServerHandleNextProtoNegoXtn(sslSocket *ss,
|
| - PRUint16 ex_type, SECItem *data);
|
| + PRUint16 ex_type, SECItem *data);
|
| static SECStatus ssl3_ServerHandleAppProtoXtn(sslSocket *ss, PRUint16 ex_type,
|
| SECItem *data);
|
| static PRInt32 ssl3_ClientSendNextProtoNegoXtn(sslSocket *ss, PRBool append,
|
| @@ -69,34 +69,40 @@ static PRInt32 ssl3_ClientSendUseSRTPXtn(sslSocket *ss, PRBool append,
|
| PRUint32 maxBytes);
|
| static PRInt32 ssl3_ServerSendUseSRTPXtn(sslSocket *ss, PRBool append,
|
| PRUint32 maxBytes);
|
| -static SECStatus ssl3_ClientHandleUseSRTPXtn(sslSocket * ss, PRUint16 ex_type,
|
| +static SECStatus ssl3_ClientHandleUseSRTPXtn(sslSocket *ss, PRUint16 ex_type,
|
| SECItem *data);
|
| -static SECStatus ssl3_ServerHandleUseSRTPXtn(sslSocket * ss, PRUint16 ex_type,
|
| +static SECStatus ssl3_ServerHandleUseSRTPXtn(sslSocket *ss, PRUint16 ex_type,
|
| SECItem *data);
|
| static SECStatus ssl3_ClientHandleChannelIDXtn(sslSocket *ss,
|
| - PRUint16 ex_type, SECItem *data);
|
| + PRUint16 ex_type, SECItem *data);
|
| static PRInt32 ssl3_ClientSendChannelIDXtn(sslSocket *ss, PRBool append,
|
| - PRUint32 maxBytes);
|
| -static PRInt32 ssl3_ServerSendStatusRequestXtn(sslSocket * ss,
|
| - PRBool append, PRUint32 maxBytes);
|
| + PRUint32 maxBytes);
|
| +static PRInt32 ssl3_ServerSendStatusRequestXtn(sslSocket *ss,
|
| + PRBool append, PRUint32 maxBytes);
|
| static SECStatus ssl3_ServerHandleStatusRequestXtn(sslSocket *ss,
|
| - PRUint16 ex_type, SECItem *data);
|
| + PRUint16 ex_type, SECItem *data);
|
| static SECStatus ssl3_ClientHandleStatusRequestXtn(sslSocket *ss,
|
| PRUint16 ex_type,
|
| SECItem *data);
|
| -static PRInt32 ssl3_ClientSendStatusRequestXtn(sslSocket * ss, PRBool append,
|
| +static PRInt32 ssl3_ClientSendStatusRequestXtn(sslSocket *ss, PRBool append,
|
| PRUint32 maxBytes);
|
| static PRInt32 ssl3_ClientSendSigAlgsXtn(sslSocket *ss, PRBool append,
|
| PRUint32 maxBytes);
|
| static SECStatus ssl3_ServerHandleSigAlgsXtn(sslSocket *ss, PRUint16 ex_type,
|
| SECItem *data);
|
| +
|
| static PRInt32 ssl3_ClientSendSignedCertTimestampXtn(sslSocket *ss,
|
| PRBool append,
|
| PRUint32 maxBytes);
|
| static SECStatus ssl3_ClientHandleSignedCertTimestampXtn(sslSocket *ss,
|
| PRUint16 ex_type,
|
| SECItem *data);
|
| -
|
| +static PRInt32 ssl3_ServerSendSignedCertTimestampXtn(sslSocket *ss,
|
| + PRBool append,
|
| + PRUint32 maxBytes);
|
| +static SECStatus ssl3_ServerHandleSignedCertTimestampXtn(sslSocket *ss,
|
| + PRUint16 ex_type,
|
| + SECItem *data);
|
| static PRInt32 ssl3_ClientSendDraftVersionXtn(sslSocket *ss, PRBool append,
|
| PRUint32 maxBytes);
|
| static SECStatus ssl3_ServerHandleDraftVersionXtn(sslSocket *ss, PRUint16 ex_type,
|
| @@ -106,7 +112,14 @@ static PRInt32 ssl3_SendExtendedMasterSecretXtn(sslSocket *ss, PRBool append,
|
| static SECStatus ssl3_HandleExtendedMasterSecretXtn(sslSocket *ss,
|
| PRUint16 ex_type,
|
| SECItem *data);
|
| -
|
| +static PRInt32 tls13_ClientSendKeyShareXtn(sslSocket *ss, PRBool append,
|
| + PRUint32 maxBytes);
|
| +static SECStatus tls13_ClientHandleKeyShareXtn(sslSocket *ss,
|
| + PRUint16 ex_type,
|
| + SECItem *data);
|
| +static SECStatus tls13_ServerHandleKeyShareXtn(sslSocket *ss,
|
| + PRUint16 ex_type,
|
| + SECItem *data);
|
|
|
| /*
|
| * Write bytes. Using this function means the SECItem structure
|
| @@ -134,24 +147,25 @@ static SECStatus
|
| ssl3_AppendNumberToItem(SECItem *item, PRUint32 num, PRInt32 lenSize)
|
| {
|
| SECStatus rv;
|
| - PRUint8 b[4];
|
| - PRUint8 * p = b;
|
| + PRUint8 b[4];
|
| + PRUint8 *p = b;
|
|
|
| switch (lenSize) {
|
| - case 4:
|
| - *p++ = (PRUint8) (num >> 24);
|
| - case 3:
|
| - *p++ = (PRUint8) (num >> 16);
|
| - case 2:
|
| - *p++ = (PRUint8) (num >> 8);
|
| - case 1:
|
| - *p = (PRUint8) num;
|
| + case 4:
|
| + *p++ = (PRUint8)(num >> 24);
|
| + case 3:
|
| + *p++ = (PRUint8)(num >> 16);
|
| + case 2:
|
| + *p++ = (PRUint8)(num >> 8);
|
| + case 1:
|
| + *p = (PRUint8)num;
|
| }
|
| rv = ssl3_AppendToItem(item, &b[0], lenSize);
|
| return rv;
|
| }
|
|
|
| -static SECStatus ssl3_SessionTicketShutdown(void* appData, void* nssData)
|
| +static SECStatus
|
| +ssl3_SessionTicketShutdown(void *appData, void *nssData)
|
| {
|
| if (session_ticket_enc_key_pkcs11) {
|
| PK11_FreeSymKey(session_ticket_enc_key_pkcs11);
|
| @@ -162,11 +176,10 @@ static SECStatus ssl3_SessionTicketShutdown(void* appData, void* nssData)
|
| session_ticket_mac_key_pkcs11 = NULL;
|
| }
|
| PORT_Memset(&generate_session_keys_once, 0,
|
| - sizeof(generate_session_keys_once));
|
| + sizeof(generate_session_keys_once));
|
| return SECSuccess;
|
| }
|
|
|
| -
|
| static PRStatus
|
| ssl3_GenerateSessionTicketKeysPKCS11(void *data)
|
| {
|
| @@ -177,16 +190,16 @@ ssl3_GenerateSessionTicketKeysPKCS11(void *data)
|
|
|
| if (svrPrivKey == NULL || svrPubKey == NULL) {
|
| SSL_DBG(("%d: SSL[%d]: Pub or priv key(s) is NULL.",
|
| - SSL_GETPID(), ss->fd));
|
| + SSL_GETPID(), ss->fd));
|
| goto loser;
|
| }
|
|
|
| /* Get a copy of the session keys from shared memory. */
|
| PORT_Memcpy(key_name, SESS_TICKET_KEY_NAME_PREFIX,
|
| - sizeof(SESS_TICKET_KEY_NAME_PREFIX));
|
| + sizeof(SESS_TICKET_KEY_NAME_PREFIX));
|
| if (!ssl_GetSessionTicketKeysPKCS11(svrPrivKey, svrPubKey,
|
| - ss->pkcs11PinArg, &key_name[SESS_TICKET_KEY_NAME_PREFIX_LEN],
|
| - &session_ticket_enc_key_pkcs11, &session_ticket_mac_key_pkcs11))
|
| + ss->pkcs11PinArg, &key_name[SESS_TICKET_KEY_NAME_PREFIX_LEN],
|
| + &session_ticket_enc_key_pkcs11, &session_ticket_mac_key_pkcs11))
|
| return PR_FAILURE;
|
|
|
| rv = NSS_RegisterShutdown(ssl3_SessionTicketShutdown, NULL);
|
| @@ -205,7 +218,8 @@ ssl3_GetSessionTicketKeysPKCS11(sslSocket *ss, PK11SymKey **aes_key,
|
| PK11SymKey **mac_key)
|
| {
|
| if (PR_CallOnceWithArg(&generate_session_keys_once,
|
| - ssl3_GenerateSessionTicketKeysPKCS11, ss) != PR_SUCCESS)
|
| + ssl3_GenerateSessionTicketKeysPKCS11, ss) !=
|
| + PR_SUCCESS)
|
| return SECFailure;
|
|
|
| if (session_ticket_enc_key_pkcs11 == NULL ||
|
| @@ -222,10 +236,10 @@ static PRStatus
|
| ssl3_GenerateSessionTicketKeys(void)
|
| {
|
| PORT_Memcpy(key_name, SESS_TICKET_KEY_NAME_PREFIX,
|
| - sizeof(SESS_TICKET_KEY_NAME_PREFIX));
|
| + sizeof(SESS_TICKET_KEY_NAME_PREFIX));
|
|
|
| if (!ssl_GetSessionTicketKeys(&key_name[SESS_TICKET_KEY_NAME_PREFIX_LEN],
|
| - session_ticket_enc_key, session_ticket_mac_key))
|
| + session_ticket_enc_key, session_ticket_mac_key))
|
| return PR_FAILURE;
|
|
|
| session_ticket_keys_initialized = PR_TRUE;
|
| @@ -234,11 +248,11 @@ ssl3_GenerateSessionTicketKeys(void)
|
|
|
| static SECStatus
|
| ssl3_GetSessionTicketKeys(const unsigned char **aes_key,
|
| - PRUint32 *aes_key_length, const unsigned char **mac_key,
|
| - PRUint32 *mac_key_length)
|
| + PRUint32 *aes_key_length, const unsigned char **mac_key,
|
| + PRUint32 *mac_key_length)
|
| {
|
| if (PR_CallOnce(&generate_session_keys_once,
|
| - ssl3_GenerateSessionTicketKeys) != PR_SUCCESS)
|
| + ssl3_GenerateSessionTicketKeys) != PR_SUCCESS)
|
| return SECFailure;
|
|
|
| if (!session_ticket_keys_initialized)
|
| @@ -259,38 +273,40 @@ ssl3_GetSessionTicketKeys(const unsigned char **aes_key,
|
| */
|
| /* This table is used by the server, to handle client hello extensions. */
|
| static const ssl3HelloExtensionHandler clientHelloHandlers[] = {
|
| - { ssl_server_name_xtn, &ssl3_HandleServerNameXtn },
|
| + { ssl_server_name_xtn, &ssl3_HandleServerNameXtn },
|
| #ifndef NSS_DISABLE_ECC
|
| - { ssl_elliptic_curves_xtn, &ssl3_HandleSupportedCurvesXtn },
|
| - { ssl_ec_point_formats_xtn, &ssl3_HandleSupportedPointFormatsXtn },
|
| + { ssl_elliptic_curves_xtn, &ssl3_HandleSupportedCurvesXtn },
|
| + { ssl_ec_point_formats_xtn, &ssl3_HandleSupportedPointFormatsXtn },
|
| #endif
|
| - { ssl_session_ticket_xtn, &ssl3_ServerHandleSessionTicketXtn },
|
| + { ssl_session_ticket_xtn, &ssl3_ServerHandleSessionTicketXtn },
|
| { ssl_renegotiation_info_xtn, &ssl3_HandleRenegotiationInfoXtn },
|
| - { ssl_next_proto_nego_xtn, &ssl3_ServerHandleNextProtoNegoXtn },
|
| + { ssl_next_proto_nego_xtn, &ssl3_ServerHandleNextProtoNegoXtn },
|
| { ssl_app_layer_protocol_xtn, &ssl3_ServerHandleAppProtoXtn },
|
| - { ssl_use_srtp_xtn, &ssl3_ServerHandleUseSRTPXtn },
|
| - { ssl_cert_status_xtn, &ssl3_ServerHandleStatusRequestXtn },
|
| + { ssl_use_srtp_xtn, &ssl3_ServerHandleUseSRTPXtn },
|
| + { ssl_cert_status_xtn, &ssl3_ServerHandleStatusRequestXtn },
|
| { ssl_signature_algorithms_xtn, &ssl3_ServerHandleSigAlgsXtn },
|
| { ssl_tls13_draft_version_xtn, &ssl3_ServerHandleDraftVersionXtn },
|
| { ssl_extended_master_secret_xtn, &ssl3_HandleExtendedMasterSecretXtn },
|
| + { ssl_signed_cert_timestamp_xtn, &ssl3_ServerHandleSignedCertTimestampXtn },
|
| + { ssl_tls13_key_share_xtn, &tls13_ServerHandleKeyShareXtn },
|
| { -1, NULL }
|
| };
|
|
|
| /* These two tables are used by the client, to handle server hello
|
| * extensions. */
|
| static const ssl3HelloExtensionHandler serverHelloHandlersTLS[] = {
|
| - { ssl_server_name_xtn, &ssl3_HandleServerNameXtn },
|
| + { ssl_server_name_xtn, &ssl3_HandleServerNameXtn },
|
| /* TODO: add a handler for ssl_ec_point_formats_xtn */
|
| - { ssl_session_ticket_xtn, &ssl3_ClientHandleSessionTicketXtn },
|
| + { ssl_session_ticket_xtn, &ssl3_ClientHandleSessionTicketXtn },
|
| { ssl_renegotiation_info_xtn, &ssl3_HandleRenegotiationInfoXtn },
|
| - { ssl_next_proto_nego_xtn, &ssl3_ClientHandleNextProtoNegoXtn },
|
| + { ssl_next_proto_nego_xtn, &ssl3_ClientHandleNextProtoNegoXtn },
|
| { ssl_app_layer_protocol_xtn, &ssl3_ClientHandleAppProtoXtn },
|
| - { ssl_use_srtp_xtn, &ssl3_ClientHandleUseSRTPXtn },
|
| - { ssl_channel_id_xtn, &ssl3_ClientHandleChannelIDXtn },
|
| - { ssl_cert_status_xtn, &ssl3_ClientHandleStatusRequestXtn },
|
| + { ssl_use_srtp_xtn, &ssl3_ClientHandleUseSRTPXtn },
|
| + { ssl_channel_id_xtn, &ssl3_ClientHandleChannelIDXtn },
|
| + { ssl_cert_status_xtn, &ssl3_ClientHandleStatusRequestXtn },
|
| { ssl_extended_master_secret_xtn, &ssl3_HandleExtendedMasterSecretXtn },
|
| - { ssl_signed_certificate_timestamp_xtn,
|
| - &ssl3_ClientHandleSignedCertTimestampXtn },
|
| + { ssl_signed_cert_timestamp_xtn, &ssl3_ClientHandleSignedCertTimestampXtn },
|
| + { ssl_tls13_key_share_xtn, &tls13_ClientHandleKeyShareXtn },
|
| { -1, NULL }
|
| };
|
|
|
| @@ -305,37 +321,37 @@ static const ssl3HelloExtensionHandler serverHelloHandlersSSL3[] = {
|
| * The server's table of hello senders is dynamic, in the socket struct,
|
| * and sender functions are registered there.
|
| */
|
| -static const
|
| -ssl3HelloExtensionSender clientHelloSendersTLS[SSL_MAX_EXTENSIONS] = {
|
| - { ssl_server_name_xtn, &ssl3_SendServerNameXtn },
|
| - { ssl_renegotiation_info_xtn, &ssl3_SendRenegotiationInfoXtn },
|
| +static const ssl3HelloExtensionSender clientHelloSendersTLS[SSL_MAX_EXTENSIONS] =
|
| + {
|
| + { ssl_server_name_xtn, &ssl3_SendServerNameXtn },
|
| + { ssl_extended_master_secret_xtn, &ssl3_SendExtendedMasterSecretXtn },
|
| + { ssl_renegotiation_info_xtn, &ssl3_SendRenegotiationInfoXtn },
|
| #ifndef NSS_DISABLE_ECC
|
| - { ssl_elliptic_curves_xtn, &ssl3_SendSupportedCurvesXtn },
|
| - { ssl_ec_point_formats_xtn, &ssl3_SendSupportedPointFormatsXtn },
|
| + { ssl_elliptic_curves_xtn, &ssl3_SendSupportedCurvesXtn },
|
| + { ssl_ec_point_formats_xtn, &ssl3_SendSupportedPointFormatsXtn },
|
| #endif
|
| - { ssl_session_ticket_xtn, &ssl3_SendSessionTicketXtn },
|
| - { ssl_next_proto_nego_xtn, &ssl3_ClientSendNextProtoNegoXtn },
|
| - { ssl_app_layer_protocol_xtn, &ssl3_ClientSendAppProtoXtn },
|
| - { ssl_use_srtp_xtn, &ssl3_ClientSendUseSRTPXtn },
|
| - { ssl_channel_id_xtn, &ssl3_ClientSendChannelIDXtn },
|
| - { ssl_cert_status_xtn, &ssl3_ClientSendStatusRequestXtn },
|
| - { ssl_signed_certificate_timestamp_xtn,
|
| - &ssl3_ClientSendSignedCertTimestampXtn },
|
| - /* WebSphere Application Server 7.0 is intolerant to the last extension
|
| - * being zero-length. It is not intolerant of TLS 1.2, so ensure that
|
| - * signature_algorithms is at the end to guarantee a non-empty
|
| - * extension. */
|
| - { ssl_signature_algorithms_xtn, &ssl3_ClientSendSigAlgsXtn },
|
| - { ssl_tls13_draft_version_xtn, &ssl3_ClientSendDraftVersionXtn },
|
| - { ssl_extended_master_secret_xtn, &ssl3_SendExtendedMasterSecretXtn},
|
| - /* any extra entries will appear as { 0, NULL } */
|
| -};
|
| -
|
| -static const
|
| -ssl3HelloExtensionSender clientHelloSendersSSL3[SSL_MAX_EXTENSIONS] = {
|
| - { ssl_renegotiation_info_xtn, &ssl3_SendRenegotiationInfoXtn }
|
| - /* any extra entries will appear as { 0, NULL } */
|
| -};
|
| + { ssl_session_ticket_xtn, &ssl3_SendSessionTicketXtn },
|
| + { ssl_next_proto_nego_xtn, &ssl3_ClientSendNextProtoNegoXtn },
|
| + { ssl_app_layer_protocol_xtn, &ssl3_ClientSendAppProtoXtn },
|
| + { ssl_use_srtp_xtn, &ssl3_ClientSendUseSRTPXtn },
|
| + { ssl_channel_id_xtn, &ssl3_ClientSendChannelIDXtn },
|
| + { ssl_cert_status_xtn, &ssl3_ClientSendStatusRequestXtn },
|
| + { ssl_tls13_draft_version_xtn, &ssl3_ClientSendDraftVersionXtn },
|
| + { ssl_signed_cert_timestamp_xtn, &ssl3_ClientSendSignedCertTimestampXtn },
|
| + { ssl_tls13_key_share_xtn, &tls13_ClientSendKeyShareXtn },
|
| + /* Some servers (e.g. WebSphere Application Server 7.0 and Tomcat) will
|
| + * time out or terminate the connection if the last extension in the
|
| + * client hello is empty. They are not intolerant of TLS 1.2, so list
|
| + * signature_algorithms at the end. See bug 1243641. */
|
| + { ssl_signature_algorithms_xtn, &ssl3_ClientSendSigAlgsXtn },
|
| + /* any extra entries will appear as { 0, NULL } */
|
| + };
|
| +
|
| +static const ssl3HelloExtensionSender clientHelloSendersSSL3[SSL_MAX_EXTENSIONS] =
|
| + {
|
| + { ssl_renegotiation_info_xtn, &ssl3_SendRenegotiationInfoXtn }
|
| + /* any extra entries will appear as { 0, NULL } */
|
| + };
|
|
|
| static PRBool
|
| arrayContainsExtension(const PRUint16 *array, PRUint32 len, PRUint16 ex_type)
|
| @@ -349,14 +365,16 @@ arrayContainsExtension(const PRUint16 *array, PRUint32 len, PRUint16 ex_type)
|
| }
|
|
|
| PRBool
|
| -ssl3_ExtensionNegotiated(sslSocket *ss, PRUint16 ex_type) {
|
| +ssl3_ExtensionNegotiated(sslSocket *ss, PRUint16 ex_type)
|
| +{
|
| TLSExtensionData *xtnData = &ss->xtnData;
|
| return arrayContainsExtension(xtnData->negotiated,
|
| xtnData->numNegotiated, ex_type);
|
| }
|
|
|
| static PRBool
|
| -ssl3_ClientExtensionAdvertised(sslSocket *ss, PRUint16 ex_type) {
|
| +ssl3_ClientExtensionAdvertised(sslSocket *ss, PRUint16 ex_type)
|
| +{
|
| TLSExtensionData *xtnData = &ss->xtnData;
|
| return arrayContainsExtension(xtnData->advertised,
|
| xtnData->numAdvertised, ex_type);
|
| @@ -367,7 +385,7 @@ ssl3_ClientExtensionAdvertised(sslSocket *ss, PRUint16 ex_type) {
|
| * Used by client and server.
|
| */
|
| PRInt32
|
| -ssl3_SendServerNameXtn(sslSocket * ss, PRBool append,
|
| +ssl3_SendServerNameXtn(sslSocket *ss, PRBool append,
|
| PRUint32 maxBytes)
|
| {
|
| SECStatus rv;
|
| @@ -385,23 +403,28 @@ ssl3_SendServerNameXtn(sslSocket * ss, PRBool append,
|
| /* is an IP address (v4 or v6) */
|
| return 0;
|
| }
|
| - len = PORT_Strlen(ss->url);
|
| + len = PORT_Strlen(ss->url);
|
| if (append && maxBytes >= len + 9) {
|
| /* extension_type */
|
| rv = ssl3_AppendHandshakeNumber(ss, ssl_server_name_xtn, 2);
|
| - if (rv != SECSuccess) return -1;
|
| + if (rv != SECSuccess)
|
| + return -1;
|
| /* length of extension_data */
|
| rv = ssl3_AppendHandshakeNumber(ss, len + 5, 2);
|
| - if (rv != SECSuccess) return -1;
|
| + if (rv != SECSuccess)
|
| + return -1;
|
| /* length of server_name_list */
|
| rv = ssl3_AppendHandshakeNumber(ss, len + 3, 2);
|
| - if (rv != SECSuccess) return -1;
|
| + if (rv != SECSuccess)
|
| + return -1;
|
| /* Name Type (sni_host_name) */
|
| - rv = ssl3_AppendHandshake(ss, "\0", 1);
|
| - if (rv != SECSuccess) return -1;
|
| + rv = ssl3_AppendHandshake(ss, "\0", 1);
|
| + if (rv != SECSuccess)
|
| + return -1;
|
| /* HostName (length and value) */
|
| rv = ssl3_AppendHandshakeVariable(ss, (PRUint8 *)ss->url, len, 2);
|
| - if (rv != SECSuccess) return -1;
|
| + if (rv != SECSuccess)
|
| + return -1;
|
| if (!ss->sec.isServer) {
|
| TLSExtensionData *xtnData = &ss->xtnData;
|
| xtnData->advertised[xtnData->numAdvertised++] =
|
| @@ -413,23 +436,25 @@ ssl3_SendServerNameXtn(sslSocket * ss, PRBool append,
|
| /* Server side */
|
| if (append && maxBytes >= 4) {
|
| rv = ssl3_AppendHandshakeNumber(ss, ssl_server_name_xtn, 2);
|
| - if (rv != SECSuccess) return -1;
|
| + if (rv != SECSuccess)
|
| + return -1;
|
| /* length of extension_data */
|
| rv = ssl3_AppendHandshakeNumber(ss, 0, 2);
|
| - if (rv != SECSuccess) return -1;
|
| + if (rv != SECSuccess)
|
| + return -1;
|
| }
|
| return 4;
|
| }
|
|
|
| /* handle an incoming SNI extension, by ignoring it. */
|
| SECStatus
|
| -ssl3_HandleServerNameXtn(sslSocket * ss, PRUint16 ex_type, SECItem *data)
|
| +ssl3_HandleServerNameXtn(sslSocket *ss, PRUint16 ex_type, SECItem *data)
|
| {
|
| SECItem *names = NULL;
|
| PRUint32 listCount = 0, namesPos = 0, i;
|
| TLSExtensionData *xtnData = &ss->xtnData;
|
| - SECItem ldata;
|
| - PRInt32 listLenBytes = 0;
|
| + SECItem ldata;
|
| + PRInt32 listLenBytes = 0;
|
|
|
| if (!ss->sec.isServer) {
|
| return SECSuccess; /* ignore extension */
|
| @@ -476,15 +501,15 @@ ssl3_HandleServerNameXtn(sslSocket * ss, PRUint16 ex_type, SECItem *data)
|
| if (!names) {
|
| return SECFailure;
|
| }
|
| - for (i = 0;i < listCount;i++) {
|
| + for (i = 0; i < listCount; i++) {
|
| unsigned int j;
|
| - PRInt32 type;
|
| + PRInt32 type;
|
| SECStatus rv;
|
| PRBool nametypePresent = PR_FALSE;
|
| /* Name Type (sni_host_name) */
|
| type = ssl3_ConsumeHandshakeNumber(ss, 1, &data->data, &data->len);
|
| /* Check if we have such type in the list */
|
| - for (j = 0;j < listCount && names[j].data;j++) {
|
| + for (j = 0; j < listCount && names[j].data; j++) {
|
| /* TODO bug 998524: .type is not assigned a value */
|
| if (names[j].type == type) {
|
| nametypePresent = PR_TRUE;
|
| @@ -521,9 +546,9 @@ ssl3_HandleServerNameXtn(sslSocket * ss, PRUint16 ex_type, SECItem *data)
|
| */
|
| PRInt32
|
| ssl3_SendSessionTicketXtn(
|
| - sslSocket * ss,
|
| - PRBool append,
|
| - PRUint32 maxBytes)
|
| + sslSocket *ss,
|
| + PRBool append,
|
| + PRUint32 maxBytes)
|
| {
|
| PRInt32 extension_length;
|
| NewSessionTicket *session_ticket = NULL;
|
| @@ -556,9 +581,10 @@ ssl3_SendSessionTicketXtn(
|
| if (ss->xtnData.ticketTimestampVerified) {
|
| extension_length += session_ticket->ticket.len;
|
| } else if (!append &&
|
| - (session_ticket->ticket_lifetime_hint == 0 ||
|
| - (session_ticket->ticket_lifetime_hint +
|
| - session_ticket->received_timestamp > ssl_Time()))) {
|
| + (session_ticket->ticket_lifetime_hint == 0 ||
|
| + (session_ticket->ticket_lifetime_hint +
|
| + session_ticket->received_timestamp >
|
| + ssl_Time()))) {
|
| extension_length += session_ticket->ticket.len;
|
| ss->xtnData.ticketTimestampVerified = PR_TRUE;
|
| }
|
| @@ -578,7 +604,7 @@ ssl3_SendSessionTicketXtn(
|
| if (session_ticket && session_ticket->ticket.data &&
|
| ss->xtnData.ticketTimestampVerified) {
|
| rv = ssl3_AppendHandshakeVariable(ss, session_ticket->ticket.data,
|
| - session_ticket->ticket.len, 2);
|
| + session_ticket->ticket.len, 2);
|
| ss->xtnData.ticketTimestampVerified = PR_FALSE;
|
| ss->xtnData.sentSessionTicketInClientHello = PR_TRUE;
|
| } else {
|
| @@ -595,14 +621,14 @@ ssl3_SendSessionTicketXtn(
|
| }
|
| return extension_length;
|
|
|
| - loser:
|
| +loser:
|
| ss->xtnData.ticketTimestampVerified = PR_FALSE;
|
| return -1;
|
| }
|
|
|
| /* handle an incoming Next Protocol Negotiation extension. */
|
| static SECStatus
|
| -ssl3_ServerHandleNextProtoNegoXtn(sslSocket * ss, PRUint16 ex_type,
|
| +ssl3_ServerHandleNextProtoNegoXtn(sslSocket *ss, PRUint16 ex_type,
|
| SECItem *data)
|
| {
|
| if (ss->firstHsDone || data->len != 0) {
|
| @@ -624,12 +650,12 @@ ssl3_ServerHandleNextProtoNegoXtn(sslSocket * ss, PRUint16 ex_type,
|
| * of the lengths may be 0 and the sum of the lengths must equal the length of
|
| * the block. */
|
| SECStatus
|
| -ssl3_ValidateNextProtoNego(const unsigned char* data, unsigned int length)
|
| +ssl3_ValidateNextProtoNego(const unsigned char *data, unsigned int length)
|
| {
|
| unsigned int offset = 0;
|
|
|
| while (offset < length) {
|
| - unsigned int newOffset = offset + 1 + (unsigned int) data[offset];
|
| + unsigned int newOffset = offset + 1 + (unsigned int)data[offset];
|
| /* Reject embedded nulls to protect against buggy applications that
|
| * store protocol identifiers in null-terminated strings.
|
| */
|
| @@ -725,7 +751,7 @@ ssl3_ServerHandleAppProtoXtn(sslSocket *ss, PRUint16 ex_type, SECItem *data)
|
|
|
| rv = ssl3_SelectAppProtocol(ss, ex_type, data);
|
| if (rv != SECSuccess) {
|
| - return rv;
|
| + return rv;
|
| }
|
|
|
| /* prepare to send back a response, if we negotiated */
|
| @@ -819,7 +845,7 @@ ssl3_ClientHandleAppProtoXtn(sslSocket *ss, PRUint16 ex_type, SECItem *data)
|
| }
|
|
|
| static PRInt32
|
| -ssl3_ClientSendNextProtoNegoXtn(sslSocket * ss, PRBool append,
|
| +ssl3_ClientSendNextProtoNegoXtn(sslSocket *ss, PRBool append,
|
| PRUint32 maxBytes)
|
| {
|
| PRInt32 extension_length;
|
| @@ -843,7 +869,7 @@ ssl3_ClientSendNextProtoNegoXtn(sslSocket * ss, PRBool append,
|
| if (rv != SECSuccess)
|
| goto loser;
|
| ss->xtnData.advertised[ss->xtnData.numAdvertised++] =
|
| - ssl_next_proto_nego_xtn;
|
| + ssl_next_proto_nego_xtn;
|
| }
|
|
|
| return extension_length;
|
| @@ -853,7 +879,7 @@ loser:
|
| }
|
|
|
| static PRInt32
|
| -ssl3_ClientSendAppProtoXtn(sslSocket * ss, PRBool append, PRUint32 maxBytes)
|
| +ssl3_ClientSendAppProtoXtn(sslSocket *ss, PRBool append, PRUint32 maxBytes)
|
| {
|
| PRInt32 extension_length;
|
| unsigned char *alpn_protos = NULL;
|
| @@ -909,7 +935,7 @@ ssl3_ClientSendAppProtoXtn(sslSocket * ss, PRBool append, PRUint32 maxBytes)
|
| goto loser;
|
| }
|
| ss->xtnData.advertised[ss->xtnData.numAdvertised++] =
|
| - ssl_app_layer_protocol_xtn;
|
| + ssl_app_layer_protocol_xtn;
|
| }
|
|
|
| return extension_length;
|
| @@ -922,7 +948,7 @@ loser:
|
| }
|
|
|
| static PRInt32
|
| -ssl3_ServerSendAppProtoXtn(sslSocket * ss, PRBool append, PRUint32 maxBytes)
|
| +ssl3_ServerSendAppProtoXtn(sslSocket *ss, PRBool append, PRUint32 maxBytes)
|
| {
|
| PRInt32 extension_length;
|
|
|
| @@ -966,30 +992,30 @@ ssl3_ServerSendAppProtoXtn(sslSocket * ss, PRBool append, PRUint32 maxBytes)
|
|
|
| static SECStatus
|
| ssl3_ClientHandleChannelIDXtn(sslSocket *ss, PRUint16 ex_type,
|
| - SECItem *data)
|
| + SECItem *data)
|
| {
|
| PORT_Assert(ss->getChannelID != NULL);
|
|
|
| if (data->len) {
|
| - PORT_SetError(SSL_ERROR_BAD_CHANNEL_ID_DATA);
|
| - return SECFailure;
|
| + PORT_SetError(SSL_ERROR_BAD_CHANNEL_ID_DATA);
|
| + return SECFailure;
|
| }
|
| ss->xtnData.negotiated[ss->xtnData.numNegotiated++] = ex_type;
|
| return SECSuccess;
|
| }
|
|
|
| static PRInt32
|
| -ssl3_ClientSendChannelIDXtn(sslSocket * ss, PRBool append,
|
| - PRUint32 maxBytes)
|
| +ssl3_ClientSendChannelIDXtn(sslSocket *ss, PRBool append,
|
| + PRUint32 maxBytes)
|
| {
|
| PRInt32 extension_length = 4;
|
|
|
| if (!ss->getChannelID)
|
| - return 0;
|
| + return 0;
|
|
|
| if (maxBytes < extension_length) {
|
| - PORT_Assert(0);
|
| - return 0;
|
| + PORT_Assert(0);
|
| + return 0;
|
| }
|
|
|
| if (ss->sec.ci.sid->cached != never_cached &&
|
| @@ -998,19 +1024,19 @@ ssl3_ClientSendChannelIDXtn(sslSocket * ss, PRBool append,
|
| * do ChannelID on the original connection: without ChannelID on the
|
| * original connection we didn't record the handshake hashes needed for
|
| * the signature. */
|
| - return 0;
|
| + return 0;
|
| }
|
|
|
| if (append) {
|
| - SECStatus rv;
|
| - rv = ssl3_AppendHandshakeNumber(ss, ssl_channel_id_xtn, 2);
|
| - if (rv != SECSuccess)
|
| - goto loser;
|
| - rv = ssl3_AppendHandshakeNumber(ss, 0, 2);
|
| - if (rv != SECSuccess)
|
| - goto loser;
|
| - ss->xtnData.advertised[ss->xtnData.numAdvertised++] =
|
| - ssl_channel_id_xtn;
|
| + SECStatus rv;
|
| + rv = ssl3_AppendHandshakeNumber(ss, ssl_channel_id_xtn, 2);
|
| + if (rv != SECSuccess)
|
| + goto loser;
|
| + rv = ssl3_AppendHandshakeNumber(ss, 0, 2);
|
| + if (rv != SECSuccess)
|
| + goto loser;
|
| + ss->xtnData.advertised[ss->xtnData.numAdvertised++] =
|
| + ssl_channel_id_xtn;
|
| }
|
|
|
| return extension_length;
|
| @@ -1021,11 +1047,11 @@ loser:
|
|
|
| static SECStatus
|
| ssl3_ClientHandleStatusRequestXtn(sslSocket *ss, PRUint16 ex_type,
|
| - SECItem *data)
|
| + SECItem *data)
|
| {
|
| /* The echoed extension must be empty. */
|
| if (data->len != 0) {
|
| - return SECSuccess; /* Ignore the extension. */
|
| + return SECSuccess; /* Ignore the extension. */
|
| }
|
|
|
| /* Keep track of negotiated extensions. */
|
| @@ -1036,28 +1062,29 @@ ssl3_ClientHandleStatusRequestXtn(sslSocket *ss, PRUint16 ex_type,
|
|
|
| static PRInt32
|
| ssl3_ServerSendStatusRequestXtn(
|
| - sslSocket * ss,
|
| - PRBool append,
|
| - PRUint32 maxBytes)
|
| + sslSocket *ss,
|
| + PRBool append,
|
| + PRUint32 maxBytes)
|
| {
|
| PRInt32 extension_length;
|
| + SSLKEAType effectiveExchKeyType;
|
| SECStatus rv;
|
| - int i;
|
| - PRBool haveStatus = PR_FALSE;
|
|
|
| - for (i = kt_null; i < kt_kea_size; i++) {
|
| - /* TODO: This is a temporary workaround.
|
| - * The correct code needs to see if we have an OCSP response for
|
| - * the server certificate being used, rather than if we have any
|
| - * OCSP response. See also ssl3_SendCertificateStatus.
|
| - */
|
| - if (ss->certStatusArray[i] && ss->certStatusArray[i]->len) {
|
| - haveStatus = PR_TRUE;
|
| - break;
|
| - }
|
| + /* ssl3_SendCertificateStatus (which sents the certificate status data)
|
| + * uses the exact same logic to select the server certificate
|
| + * and determine if we have the status for that certificate. */
|
| +
|
| + if (ss->ssl3.hs.kea_def->kea == kea_ecdhe_rsa ||
|
| + ss->ssl3.hs.kea_def->kea == kea_dhe_rsa) {
|
| + effectiveExchKeyType = ssl_kea_rsa;
|
| + } else {
|
| + effectiveExchKeyType = ss->ssl3.hs.kea_def->exchKeyType;
|
| }
|
| - if (!haveStatus)
|
| +
|
| + if (!ss->certStatusArray[effectiveExchKeyType] ||
|
| + !ss->certStatusArray[effectiveExchKeyType]->len) {
|
| return 0;
|
| + }
|
|
|
| extension_length = 2 + 2;
|
| if (maxBytes < (PRUint32)extension_length) {
|
| @@ -1072,6 +1099,7 @@ ssl3_ServerSendStatusRequestXtn(
|
| rv = ssl3_AppendHandshakeNumber(ss, 0, 2);
|
| if (rv != SECSuccess)
|
| return -1;
|
| + /* The certificate status data is sent in ssl3_SendCertificateStatus. */
|
| }
|
|
|
| return extension_length;
|
| @@ -1080,13 +1108,13 @@ ssl3_ServerSendStatusRequestXtn(
|
| /* ssl3_ClientSendStatusRequestXtn builds the status_request extension on the
|
| * client side. See RFC 4366 section 3.6. */
|
| static PRInt32
|
| -ssl3_ClientSendStatusRequestXtn(sslSocket * ss, PRBool append,
|
| - PRUint32 maxBytes)
|
| +ssl3_ClientSendStatusRequestXtn(sslSocket *ss, PRBool append,
|
| + PRUint32 maxBytes)
|
| {
|
| PRInt32 extension_length;
|
|
|
| if (!ss->opt.enableOCSPStapling)
|
| - return 0;
|
| + return 0;
|
|
|
| /* extension_type (2-bytes) +
|
| * length(extension_data) (2-bytes) +
|
| @@ -1097,37 +1125,37 @@ ssl3_ClientSendStatusRequestXtn(sslSocket * ss, PRBool append,
|
| extension_length = 9;
|
|
|
| if (maxBytes < (PRUint32)extension_length) {
|
| - PORT_Assert(0);
|
| - return 0;
|
| + PORT_Assert(0);
|
| + return 0;
|
| }
|
| if (append) {
|
| - SECStatus rv;
|
| - TLSExtensionData *xtnData;
|
| -
|
| - /* extension_type */
|
| - rv = ssl3_AppendHandshakeNumber(ss, ssl_cert_status_xtn, 2);
|
| - if (rv != SECSuccess)
|
| - return -1;
|
| - rv = ssl3_AppendHandshakeNumber(ss, extension_length - 4, 2);
|
| - if (rv != SECSuccess)
|
| - return -1;
|
| - rv = ssl3_AppendHandshakeNumber(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);
|
| - 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);
|
| - if (rv != SECSuccess)
|
| - return -1;
|
| -
|
| - xtnData = &ss->xtnData;
|
| - xtnData->advertised[xtnData->numAdvertised++] = ssl_cert_status_xtn;
|
| + SECStatus rv;
|
| + TLSExtensionData *xtnData;
|
| +
|
| + /* extension_type */
|
| + rv = ssl3_AppendHandshakeNumber(ss, ssl_cert_status_xtn, 2);
|
| + if (rv != SECSuccess)
|
| + return -1;
|
| + rv = ssl3_AppendHandshakeNumber(ss, extension_length - 4, 2);
|
| + if (rv != SECSuccess)
|
| + return -1;
|
| + rv = ssl3_AppendHandshakeNumber(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);
|
| + 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);
|
| + if (rv != SECSuccess)
|
| + return -1;
|
| +
|
| + xtnData = &ss->xtnData;
|
| + xtnData->advertised[xtnData->numAdvertised++] = ssl_cert_status_xtn;
|
| }
|
| return extension_length;
|
| }
|
| @@ -1140,74 +1168,77 @@ SECStatus
|
| ssl3_SendNewSessionTicket(sslSocket *ss)
|
| {
|
| PRUint32 i;
|
| - SECStatus rv;
|
| - NewSessionTicket ticket;
|
| - SECItem plaintext;
|
| - SECItem plaintext_item = {0, NULL, 0};
|
| - SECItem ciphertext = {0, NULL, 0};
|
| - PRUint32 ciphertext_length;
|
| - PRBool ms_is_wrapped;
|
| - unsigned char wrapped_ms[SSL3_MASTER_SECRET_LENGTH];
|
| - SECItem ms_item = {0, NULL, 0};
|
| - SSL3KEAType effectiveExchKeyType = ssl_kea_null;
|
| - PRUint32 padding_length;
|
| - PRUint32 message_length;
|
| - PRUint32 cert_length;
|
| - PRUint8 length_buf[4];
|
| - PRUint32 now;
|
| - PK11SymKey *aes_key_pkcs11;
|
| - PK11SymKey *mac_key_pkcs11;
|
| + SECStatus rv;
|
| + NewSessionTicket ticket;
|
| + SECItem plaintext;
|
| + SECItem plaintext_item = { 0, NULL, 0 };
|
| + SECItem ciphertext = { 0, NULL, 0 };
|
| + PRUint32 ciphertext_length;
|
| + PRBool ms_is_wrapped;
|
| + unsigned char wrapped_ms[SSL3_MASTER_SECRET_LENGTH];
|
| + SECItem ms_item = { 0, NULL, 0 };
|
| + SSL3KEAType effectiveExchKeyType = ssl_kea_null;
|
| + PRUint32 padding_length;
|
| + PRUint32 message_length;
|
| + PRUint32 cert_length = 0;
|
| + PRUint8 length_buf[4];
|
| + PRUint32 now;
|
| + PK11SymKey *aes_key_pkcs11;
|
| + PK11SymKey *mac_key_pkcs11;
|
| #ifndef NO_PKCS11_BYPASS
|
| const unsigned char *aes_key;
|
| const unsigned char *mac_key;
|
| - PRUint32 aes_key_length;
|
| - PRUint32 mac_key_length;
|
| - PRUint64 aes_ctx_buf[MAX_CIPHER_CONTEXT_LLONGS];
|
| - AESContext *aes_ctx;
|
| + PRUint32 aes_key_length;
|
| + PRUint32 mac_key_length;
|
| + PRUint64 aes_ctx_buf[MAX_CIPHER_CONTEXT_LLONGS];
|
| + AESContext *aes_ctx;
|
| const SECHashObject *hashObj = NULL;
|
| - PRUint64 hmac_ctx_buf[MAX_MAC_CONTEXT_LLONGS];
|
| - HMACContext *hmac_ctx;
|
| + PRUint64 hmac_ctx_buf[MAX_MAC_CONTEXT_LLONGS];
|
| + HMACContext *hmac_ctx;
|
| #endif
|
| - CK_MECHANISM_TYPE cipherMech = CKM_AES_CBC;
|
| - PK11Context *aes_ctx_pkcs11;
|
| - CK_MECHANISM_TYPE macMech = CKM_SHA256_HMAC;
|
| - PK11Context *hmac_ctx_pkcs11 = NULL;
|
| - unsigned char computed_mac[TLS_EX_SESS_TICKET_MAC_LENGTH];
|
| - unsigned int computed_mac_length;
|
| - unsigned char iv[AES_BLOCK_SIZE];
|
| - SECItem ivItem;
|
| - SECItem *srvName = NULL;
|
| - PRUint32 srvNameLen = 0;
|
| - CK_MECHANISM_TYPE msWrapMech = 0; /* dummy default value,
|
| + CK_MECHANISM_TYPE cipherMech = CKM_AES_CBC;
|
| + PK11Context *aes_ctx_pkcs11;
|
| + CK_MECHANISM_TYPE macMech = CKM_SHA256_HMAC;
|
| + PK11Context *hmac_ctx_pkcs11 = NULL;
|
| + unsigned char computed_mac[TLS_EX_SESS_TICKET_MAC_LENGTH];
|
| + unsigned int computed_mac_length;
|
| + unsigned char iv[AES_BLOCK_SIZE];
|
| + SECItem ivItem;
|
| + SECItem *srvName = NULL;
|
| + PRUint32 srvNameLen = 0;
|
| + CK_MECHANISM_TYPE msWrapMech = 0; /* dummy default value,
|
| * must be >= 0 */
|
|
|
| SSL_TRC(3, ("%d: SSL3[%d]: send session_ticket handshake",
|
| SSL_GETPID(), ss->fd));
|
|
|
| - PORT_Assert( ss->opt.noLocks || ssl_HaveXmitBufLock(ss));
|
| - PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss));
|
| + PORT_Assert(ss->opt.noLocks || ssl_HaveXmitBufLock(ss));
|
| + PORT_Assert(ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss));
|
|
|
| ticket.ticket_lifetime_hint = TLS_EX_SESS_TICKET_LIFETIME_HINT;
|
| - cert_length = (ss->opt.requestCertificate && ss->sec.ci.sid->peerCert) ?
|
| - 3 + ss->sec.ci.sid->peerCert->derCert.len : 0;
|
| + if (ss->opt.requestCertificate && ss->sec.ci.sid->peerCert) {
|
| + cert_length = 3 + ss->sec.ci.sid->peerCert->derCert.len;
|
| + }
|
|
|
| /* Get IV and encryption keys */
|
| ivItem.data = iv;
|
| ivItem.len = sizeof(iv);
|
| rv = PK11_GenerateRandom(iv, sizeof(iv));
|
| - if (rv != SECSuccess) goto loser;
|
| + if (rv != SECSuccess)
|
| + goto loser;
|
|
|
| #ifndef NO_PKCS11_BYPASS
|
| if (ss->opt.bypassPKCS11) {
|
| rv = ssl3_GetSessionTicketKeys(&aes_key, &aes_key_length,
|
| - &mac_key, &mac_key_length);
|
| + &mac_key, &mac_key_length);
|
| } else
|
| #endif
|
| {
|
| rv = ssl3_GetSessionTicketKeysPKCS11(ss, &aes_key_pkcs11,
|
| - &mac_key_pkcs11);
|
| + &mac_key_pkcs11);
|
| }
|
| - if (rv != SECSuccess) goto loser;
|
| + if (rv != SECSuccess)
|
| + goto loser;
|
|
|
| if (ss->ssl3.pwSpec->msItem.len && ss->ssl3.pwSpec->msItem.data) {
|
| /* The master secret is available unwrapped. */
|
| @@ -1227,12 +1258,12 @@ ssl3_SendNewSessionTicket(sslSocket *ss)
|
| }
|
|
|
| rv = ssl3_CacheWrappedMasterSecret(ss, &sid, ss->ssl3.pwSpec,
|
| - effectiveExchKeyType);
|
| + effectiveExchKeyType);
|
| if (rv == SECSuccess) {
|
| if (sid.u.ssl3.keys.wrapped_master_secret_len > sizeof(wrapped_ms))
|
| goto loser;
|
| memcpy(wrapped_ms, sid.u.ssl3.keys.wrapped_master_secret,
|
| - sid.u.ssl3.keys.wrapped_master_secret_len);
|
| + sid.u.ssl3.keys.wrapped_master_secret_len);
|
| ms_item.data = wrapped_ms;
|
| ms_item.len = sid.u.ssl3.keys.wrapped_master_secret_len;
|
| msWrapMech = sid.u.ssl3.masterWrapMech;
|
| @@ -1249,34 +1280,35 @@ ssl3_SendNewSessionTicket(sslSocket *ss)
|
| }
|
|
|
| ciphertext_length =
|
| - sizeof(PRUint16) /* ticket_version */
|
| - + sizeof(SSL3ProtocolVersion) /* ssl_version */
|
| - + sizeof(ssl3CipherSuite) /* ciphersuite */
|
| - + 1 /* compression */
|
| - + 10 /* cipher spec parameters */
|
| - + 1 /* SessionTicket.ms_is_wrapped */
|
| - + 1 /* effectiveExchKeyType */
|
| - + 4 /* msWrapMech */
|
| - + 2 /* master_secret.length */
|
| - + ms_item.len /* master_secret */
|
| - + 1 /* client_auth_type */
|
| - + cert_length /* cert */
|
| - + 1 /* server name type */
|
| - + srvNameLen /* name len + length field */
|
| - + 1 /* extendedMasterSecretUsed */
|
| + sizeof(PRUint16) /* ticket_version */
|
| + + sizeof(SSL3ProtocolVersion) /* ssl_version */
|
| + + sizeof(ssl3CipherSuite) /* ciphersuite */
|
| + + 1 /* compression */
|
| + + 10 /* cipher spec parameters */
|
| + + 1 /* SessionTicket.ms_is_wrapped */
|
| + + 1 /* effectiveExchKeyType */
|
| + + 4 /* msWrapMech */
|
| + + 2 /* master_secret.length */
|
| + + ms_item.len /* master_secret */
|
| + + 1 /* client_auth_type */
|
| + + cert_length /* cert */
|
| + + 1 /* server name type */
|
| + + srvNameLen /* name len + length field */
|
| + + 1 /* extendedMasterSecretUsed */
|
| + sizeof(ticket.ticket_lifetime_hint);
|
| - padding_length = AES_BLOCK_SIZE -
|
| - (ciphertext_length % AES_BLOCK_SIZE);
|
| + padding_length = AES_BLOCK_SIZE -
|
| + (ciphertext_length %
|
| + AES_BLOCK_SIZE);
|
| ciphertext_length += padding_length;
|
|
|
| message_length =
|
| - sizeof(ticket.ticket_lifetime_hint) /* ticket_lifetime_hint */
|
| - + 2 /* length field for NewSessionTicket.ticket */
|
| - + SESS_TICKET_KEY_NAME_LEN /* key_name */
|
| - + AES_BLOCK_SIZE /* iv */
|
| - + 2 /* length field for NewSessionTicket.ticket.encrypted_state */
|
| - + ciphertext_length /* encrypted_state */
|
| - + TLS_EX_SESS_TICKET_MAC_LENGTH; /* mac */
|
| + sizeof(ticket.ticket_lifetime_hint) /* ticket_lifetime_hint */
|
| + + 2 /* length field for NewSessionTicket.ticket */
|
| + + SESS_TICKET_KEY_NAME_LEN /* key_name */
|
| + + AES_BLOCK_SIZE /* iv */
|
| + + 2 /* length field for NewSessionTicket.ticket.encrypted_state */
|
| + + ciphertext_length /* encrypted_state */
|
| + + TLS_EX_SESS_TICKET_MAC_LENGTH; /* mac */
|
|
|
| if (SECITEM_AllocItem(NULL, &plaintext_item, ciphertext_length) == NULL)
|
| goto loser;
|
| @@ -1285,87 +1317,109 @@ ssl3_SendNewSessionTicket(sslSocket *ss)
|
|
|
| /* ticket_version */
|
| rv = ssl3_AppendNumberToItem(&plaintext, TLS_EX_SESS_TICKET_VERSION,
|
| - sizeof(PRUint16));
|
| - if (rv != SECSuccess) goto loser;
|
| + sizeof(PRUint16));
|
| + if (rv != SECSuccess)
|
| + goto loser;
|
|
|
| /* ssl_version */
|
| rv = ssl3_AppendNumberToItem(&plaintext, ss->version,
|
| - sizeof(SSL3ProtocolVersion));
|
| - if (rv != SECSuccess) goto loser;
|
| + sizeof(SSL3ProtocolVersion));
|
| + if (rv != SECSuccess)
|
| + goto loser;
|
|
|
| /* ciphersuite */
|
| rv = ssl3_AppendNumberToItem(&plaintext, ss->ssl3.hs.cipher_suite,
|
| - sizeof(ssl3CipherSuite));
|
| - if (rv != SECSuccess) goto loser;
|
| + sizeof(ssl3CipherSuite));
|
| + if (rv != SECSuccess)
|
| + goto loser;
|
|
|
| /* compression */
|
| rv = ssl3_AppendNumberToItem(&plaintext, ss->ssl3.hs.compression, 1);
|
| - if (rv != SECSuccess) goto loser;
|
| + if (rv != SECSuccess)
|
| + goto loser;
|
|
|
| /* cipher spec parameters */
|
| rv = ssl3_AppendNumberToItem(&plaintext, ss->sec.authAlgorithm, 1);
|
| - if (rv != SECSuccess) goto loser;
|
| + if (rv != SECSuccess)
|
| + goto loser;
|
| rv = ssl3_AppendNumberToItem(&plaintext, ss->sec.authKeyBits, 4);
|
| - if (rv != SECSuccess) goto loser;
|
| + if (rv != SECSuccess)
|
| + goto loser;
|
| rv = ssl3_AppendNumberToItem(&plaintext, ss->sec.keaType, 1);
|
| - if (rv != SECSuccess) goto loser;
|
| + if (rv != SECSuccess)
|
| + goto loser;
|
| rv = ssl3_AppendNumberToItem(&plaintext, ss->sec.keaKeyBits, 4);
|
| - if (rv != SECSuccess) goto loser;
|
| + if (rv != SECSuccess)
|
| + goto loser;
|
|
|
| /* master_secret */
|
| rv = ssl3_AppendNumberToItem(&plaintext, ms_is_wrapped, 1);
|
| - if (rv != SECSuccess) goto loser;
|
| + if (rv != SECSuccess)
|
| + goto loser;
|
| rv = ssl3_AppendNumberToItem(&plaintext, effectiveExchKeyType, 1);
|
| - if (rv != SECSuccess) goto loser;
|
| + if (rv != SECSuccess)
|
| + goto loser;
|
| rv = ssl3_AppendNumberToItem(&plaintext, msWrapMech, 4);
|
| - if (rv != SECSuccess) goto loser;
|
| + if (rv != SECSuccess)
|
| + goto loser;
|
| rv = ssl3_AppendNumberToItem(&plaintext, ms_item.len, 2);
|
| - if (rv != SECSuccess) goto loser;
|
| + if (rv != SECSuccess)
|
| + goto loser;
|
| rv = ssl3_AppendToItem(&plaintext, ms_item.data, ms_item.len);
|
| - if (rv != SECSuccess) goto loser;
|
| + if (rv != SECSuccess)
|
| + goto loser;
|
|
|
| /* client_identity */
|
| if (ss->opt.requestCertificate && ss->sec.ci.sid->peerCert) {
|
| rv = ssl3_AppendNumberToItem(&plaintext, CLIENT_AUTH_CERTIFICATE, 1);
|
| - if (rv != SECSuccess) goto loser;
|
| + if (rv != SECSuccess)
|
| + goto loser;
|
| rv = ssl3_AppendNumberToItem(&plaintext,
|
| - ss->sec.ci.sid->peerCert->derCert.len, 3);
|
| - if (rv != SECSuccess) goto loser;
|
| + ss->sec.ci.sid->peerCert->derCert.len, 3);
|
| + if (rv != SECSuccess)
|
| + goto loser;
|
| rv = ssl3_AppendToItem(&plaintext,
|
| - ss->sec.ci.sid->peerCert->derCert.data,
|
| - ss->sec.ci.sid->peerCert->derCert.len);
|
| - if (rv != SECSuccess) goto loser;
|
| + ss->sec.ci.sid->peerCert->derCert.data,
|
| + ss->sec.ci.sid->peerCert->derCert.len);
|
| + if (rv != SECSuccess)
|
| + goto loser;
|
| } else {
|
| rv = ssl3_AppendNumberToItem(&plaintext, 0, 1);
|
| - if (rv != SECSuccess) goto loser;
|
| + if (rv != SECSuccess)
|
| + goto loser;
|
| }
|
|
|
| /* timestamp */
|
| now = ssl_Time();
|
| rv = ssl3_AppendNumberToItem(&plaintext, now,
|
| - sizeof(ticket.ticket_lifetime_hint));
|
| - if (rv != SECSuccess) goto loser;
|
| + sizeof(ticket.ticket_lifetime_hint));
|
| + if (rv != SECSuccess)
|
| + goto loser;
|
|
|
| if (srvNameLen) {
|
| /* Name Type (sni_host_name) */
|
| rv = ssl3_AppendNumberToItem(&plaintext, srvName->type, 1);
|
| - if (rv != SECSuccess) goto loser;
|
| + if (rv != SECSuccess)
|
| + goto loser;
|
| /* HostName (length and value) */
|
| rv = ssl3_AppendNumberToItem(&plaintext, srvName->len, 2);
|
| - if (rv != SECSuccess) goto loser;
|
| + if (rv != SECSuccess)
|
| + goto loser;
|
| rv = ssl3_AppendToItem(&plaintext, srvName->data, srvName->len);
|
| - if (rv != SECSuccess) goto loser;
|
| + if (rv != SECSuccess)
|
| + goto loser;
|
| } else {
|
| /* No Name */
|
| - rv = ssl3_AppendNumberToItem(&plaintext, (char)TLS_STE_NO_SERVER_NAME,
|
| - 1);
|
| - if (rv != SECSuccess) goto loser;
|
| + rv = ssl3_AppendNumberToItem(&plaintext, (char)TLS_STE_NO_SERVER_NAME, 1);
|
| + if (rv != SECSuccess)
|
| + goto loser;
|
| }
|
|
|
| /* extendedMasterSecretUsed */
|
| rv = ssl3_AppendNumberToItem(
|
| &plaintext, ss->sec.ci.sid->u.ssl3.keys.extendedMasterSecretUsed, 1);
|
| - if (rv != SECSuccess) goto loser;
|
| + if (rv != SECSuccess)
|
| + goto loser;
|
|
|
| PORT_Assert(plaintext.len == padding_length);
|
| for (i = 0; i < padding_length; i++)
|
| @@ -1376,45 +1430,48 @@ ssl3_SendNewSessionTicket(sslSocket *ss)
|
| goto loser;
|
| }
|
|
|
| - /* Generate encrypted portion of ticket. */
|
| +/* Generate encrypted portion of ticket. */
|
| #ifndef NO_PKCS11_BYPASS
|
| if (ss->opt.bypassPKCS11) {
|
| aes_ctx = (AESContext *)aes_ctx_buf;
|
| rv = AES_InitContext(aes_ctx, aes_key, aes_key_length, iv,
|
| - NSS_AES_CBC, 1, AES_BLOCK_SIZE);
|
| - if (rv != SECSuccess) goto loser;
|
| + NSS_AES_CBC, 1, AES_BLOCK_SIZE);
|
| + if (rv != SECSuccess)
|
| + goto loser;
|
|
|
| rv = AES_Encrypt(aes_ctx, ciphertext.data, &ciphertext.len,
|
| - ciphertext.len, plaintext_item.data,
|
| - plaintext_item.len);
|
| - if (rv != SECSuccess) goto loser;
|
| + ciphertext.len, plaintext_item.data,
|
| + plaintext_item.len);
|
| + if (rv != SECSuccess)
|
| + goto loser;
|
| } else
|
| #endif
|
| {
|
| aes_ctx_pkcs11 = PK11_CreateContextBySymKey(cipherMech,
|
| - CKA_ENCRYPT, aes_key_pkcs11, &ivItem);
|
| + CKA_ENCRYPT, aes_key_pkcs11, &ivItem);
|
| if (!aes_ctx_pkcs11)
|
| goto loser;
|
|
|
| rv = PK11_CipherOp(aes_ctx_pkcs11, ciphertext.data,
|
| - (int *)&ciphertext.len, ciphertext.len,
|
| - plaintext_item.data, plaintext_item.len);
|
| + (int *)&ciphertext.len, ciphertext.len,
|
| + plaintext_item.data, plaintext_item.len);
|
| PK11_Finalize(aes_ctx_pkcs11);
|
| PK11_DestroyContext(aes_ctx_pkcs11, PR_TRUE);
|
| - if (rv != SECSuccess) goto loser;
|
| + if (rv != SECSuccess)
|
| + goto loser;
|
| }
|
|
|
| /* Convert ciphertext length to network order. */
|
| length_buf[0] = (ciphertext.len >> 8) & 0xff;
|
| - length_buf[1] = (ciphertext.len ) & 0xff;
|
| + length_buf[1] = (ciphertext.len) & 0xff;
|
|
|
| - /* Compute MAC. */
|
| +/* Compute MAC. */
|
| #ifndef NO_PKCS11_BYPASS
|
| if (ss->opt.bypassPKCS11) {
|
| hmac_ctx = (HMACContext *)hmac_ctx_buf;
|
| hashObj = HASH_GetRawHashObject(HASH_AlgSHA256);
|
| if (HMAC_Init(hmac_ctx, hashObj, mac_key,
|
| - mac_key_length, PR_FALSE) != SECSuccess)
|
| + mac_key_length, PR_FALSE) != SECSuccess)
|
| goto loser;
|
|
|
| HMAC_Begin(hmac_ctx);
|
| @@ -1423,7 +1480,7 @@ ssl3_SendNewSessionTicket(sslSocket *ss)
|
| HMAC_Update(hmac_ctx, (unsigned char *)length_buf, 2);
|
| HMAC_Update(hmac_ctx, ciphertext.data, ciphertext.len);
|
| HMAC_Finish(hmac_ctx, computed_mac, &computed_mac_length,
|
| - sizeof(computed_mac));
|
| + sizeof(computed_mac));
|
| } else
|
| #endif
|
| {
|
| @@ -1431,49 +1488,63 @@ ssl3_SendNewSessionTicket(sslSocket *ss)
|
| macParam.data = NULL;
|
| macParam.len = 0;
|
| hmac_ctx_pkcs11 = PK11_CreateContextBySymKey(macMech,
|
| - CKA_SIGN, mac_key_pkcs11, &macParam);
|
| + CKA_SIGN, mac_key_pkcs11, &macParam);
|
| if (!hmac_ctx_pkcs11)
|
| goto loser;
|
|
|
| rv = PK11_DigestBegin(hmac_ctx_pkcs11);
|
| - if (rv != SECSuccess) goto loser;
|
| + if (rv != SECSuccess)
|
| + goto loser;
|
| rv = PK11_DigestOp(hmac_ctx_pkcs11, key_name,
|
| - SESS_TICKET_KEY_NAME_LEN);
|
| - if (rv != SECSuccess) goto loser;
|
| + SESS_TICKET_KEY_NAME_LEN);
|
| + if (rv != SECSuccess)
|
| + goto loser;
|
| rv = PK11_DigestOp(hmac_ctx_pkcs11, iv, sizeof(iv));
|
| - if (rv != SECSuccess) goto loser;
|
| + if (rv != SECSuccess)
|
| + goto loser;
|
| rv = PK11_DigestOp(hmac_ctx_pkcs11, (unsigned char *)length_buf, 2);
|
| - if (rv != SECSuccess) goto loser;
|
| + if (rv != SECSuccess)
|
| + goto loser;
|
| rv = PK11_DigestOp(hmac_ctx_pkcs11, ciphertext.data, ciphertext.len);
|
| - if (rv != SECSuccess) goto loser;
|
| + if (rv != SECSuccess)
|
| + goto loser;
|
| rv = PK11_DigestFinal(hmac_ctx_pkcs11, computed_mac,
|
| - &computed_mac_length, sizeof(computed_mac));
|
| - if (rv != SECSuccess) goto loser;
|
| + &computed_mac_length, sizeof(computed_mac));
|
| + if (rv != SECSuccess)
|
| + goto loser;
|
| }
|
|
|
| /* Serialize the handshake message. */
|
| rv = ssl3_AppendHandshakeHeader(ss, new_session_ticket, message_length);
|
| - if (rv != SECSuccess) goto loser;
|
| + if (rv != SECSuccess)
|
| + goto loser;
|
|
|
| rv = ssl3_AppendHandshakeNumber(ss, ticket.ticket_lifetime_hint,
|
| - sizeof(ticket.ticket_lifetime_hint));
|
| - if (rv != SECSuccess) goto loser;
|
| + sizeof(ticket.ticket_lifetime_hint));
|
| + if (rv != SECSuccess)
|
| + goto loser;
|
|
|
| rv = ssl3_AppendHandshakeNumber(ss,
|
| - message_length - sizeof(ticket.ticket_lifetime_hint) - 2, 2);
|
| - if (rv != SECSuccess) goto loser;
|
| + message_length - sizeof(ticket.ticket_lifetime_hint) - 2,
|
| + 2);
|
| + if (rv != SECSuccess)
|
| + goto loser;
|
|
|
| rv = ssl3_AppendHandshake(ss, key_name, SESS_TICKET_KEY_NAME_LEN);
|
| - if (rv != SECSuccess) goto loser;
|
| + if (rv != SECSuccess)
|
| + goto loser;
|
|
|
| rv = ssl3_AppendHandshake(ss, iv, sizeof(iv));
|
| - if (rv != SECSuccess) goto loser;
|
| + if (rv != SECSuccess)
|
| + goto loser;
|
|
|
| rv = ssl3_AppendHandshakeVariable(ss, ciphertext.data, ciphertext.len, 2);
|
| - if (rv != SECSuccess) goto loser;
|
| + if (rv != SECSuccess)
|
| + goto loser;
|
|
|
| rv = ssl3_AppendHandshake(ss, computed_mac, computed_mac_length);
|
| - if (rv != SECSuccess) goto loser;
|
| + if (rv != SECSuccess)
|
| + goto loser;
|
|
|
| loser:
|
| if (hmac_ctx_pkcs11)
|
| @@ -1494,7 +1565,7 @@ ssl3_ClientHandleSessionTicketXtn(sslSocket *ss, PRUint16 ex_type,
|
| SECItem *data)
|
| {
|
| if (data->len != 0) {
|
| - return SECSuccess; /* Ignore the extension. */
|
| + return SECSuccess; /* Ignore the extension. */
|
| }
|
|
|
| /* Keep track of negotiated extensions. */
|
| @@ -1528,34 +1599,34 @@ ssl3_ServerHandleSessionTicketXtn(sslSocket *ss, PRUint16 ex_type,
|
| ss->xtnData.emptySessionTicket = PR_TRUE;
|
| } else {
|
| PRUint32 i;
|
| - SECItem extension_data;
|
| + SECItem extension_data;
|
| EncryptedSessionTicket enc_session_ticket;
|
| - unsigned char computed_mac[TLS_EX_SESS_TICKET_MAC_LENGTH];
|
| - unsigned int computed_mac_length;
|
| + unsigned char computed_mac[TLS_EX_SESS_TICKET_MAC_LENGTH];
|
| + unsigned int computed_mac_length;
|
| #ifndef NO_PKCS11_BYPASS
|
| - const SECHashObject *hashObj;
|
| - const unsigned char *aes_key;
|
| - const unsigned char *mac_key;
|
| - PRUint32 aes_key_length;
|
| - PRUint32 mac_key_length;
|
| - PRUint64 hmac_ctx_buf[MAX_MAC_CONTEXT_LLONGS];
|
| - HMACContext *hmac_ctx;
|
| - PRUint64 aes_ctx_buf[MAX_CIPHER_CONTEXT_LLONGS];
|
| - AESContext *aes_ctx;
|
| + const SECHashObject *hashObj;
|
| + const unsigned char *aes_key;
|
| + const unsigned char *mac_key;
|
| + PRUint32 aes_key_length;
|
| + PRUint32 mac_key_length;
|
| + PRUint64 hmac_ctx_buf[MAX_MAC_CONTEXT_LLONGS];
|
| + HMACContext *hmac_ctx;
|
| + PRUint64 aes_ctx_buf[MAX_CIPHER_CONTEXT_LLONGS];
|
| + AESContext *aes_ctx;
|
| #endif
|
| - PK11SymKey *aes_key_pkcs11;
|
| - PK11SymKey *mac_key_pkcs11;
|
| - PK11Context *hmac_ctx_pkcs11;
|
| - CK_MECHANISM_TYPE macMech = CKM_SHA256_HMAC;
|
| - PK11Context *aes_ctx_pkcs11;
|
| - CK_MECHANISM_TYPE cipherMech = CKM_AES_CBC;
|
| - unsigned char * padding;
|
| - PRUint32 padding_length;
|
| - unsigned char *buffer;
|
| - unsigned int buffer_len;
|
| - PRInt32 temp;
|
| - SECItem cert_item;
|
| - PRInt8 nameType = TLS_STE_NO_SERVER_NAME;
|
| + PK11SymKey *aes_key_pkcs11;
|
| + PK11SymKey *mac_key_pkcs11;
|
| + PK11Context *hmac_ctx_pkcs11;
|
| + CK_MECHANISM_TYPE macMech = CKM_SHA256_HMAC;
|
| + PK11Context *aes_ctx_pkcs11;
|
| + CK_MECHANISM_TYPE cipherMech = CKM_AES_CBC;
|
| + unsigned char *padding;
|
| + PRUint32 padding_length;
|
| + unsigned char *buffer;
|
| + unsigned int buffer_len;
|
| + PRInt32 temp;
|
| + SECItem cert_item;
|
| + PRInt8 nameType = TLS_STE_NO_SERVER_NAME;
|
|
|
| /* Turn off stateless session resumption if the client sends a
|
| * SessionTicket extension, even if the extension turns out to be
|
| @@ -1572,25 +1643,25 @@ ssl3_ServerHandleSessionTicketXtn(sslSocket *ss, PRUint16 ex_type,
|
| extension_data.data = data->data; /* Keep a copy for future use. */
|
| extension_data.len = data->len;
|
|
|
| - if (ssl3_ParseEncryptedSessionTicket(ss, data, &enc_session_ticket)
|
| - != SECSuccess) {
|
| + if (ssl3_ParseEncryptedSessionTicket(ss, data, &enc_session_ticket) !=
|
| + SECSuccess) {
|
| return SECSuccess; /* Pretend it isn't there */
|
| }
|
|
|
| - /* Get session ticket keys. */
|
| +/* Get session ticket keys. */
|
| #ifndef NO_PKCS11_BYPASS
|
| if (ss->opt.bypassPKCS11) {
|
| rv = ssl3_GetSessionTicketKeys(&aes_key, &aes_key_length,
|
| - &mac_key, &mac_key_length);
|
| + &mac_key, &mac_key_length);
|
| } else
|
| #endif
|
| {
|
| rv = ssl3_GetSessionTicketKeysPKCS11(ss, &aes_key_pkcs11,
|
| - &mac_key_pkcs11);
|
| + &mac_key_pkcs11);
|
| }
|
| if (rv != SECSuccess) {
|
| SSL_DBG(("%d: SSL[%d]: Unable to get/generate session ticket keys.",
|
| - SSL_GETPID(), ss->fd));
|
| + SSL_GETPID(), ss->fd));
|
| goto loser;
|
| }
|
|
|
| @@ -1598,9 +1669,9 @@ ssl3_ServerHandleSessionTicketXtn(sslSocket *ss, PRUint16 ex_type,
|
| * from the one we have, bypass ticket processing.
|
| */
|
| if (PORT_Memcmp(enc_session_ticket.key_name, key_name,
|
| - SESS_TICKET_KEY_NAME_LEN) != 0) {
|
| + SESS_TICKET_KEY_NAME_LEN) != 0) {
|
| SSL_DBG(("%d: SSL[%d]: Session ticket key_name sent mismatch.",
|
| - SSL_GETPID(), ss->fd));
|
| + SSL_GETPID(), ss->fd));
|
| goto no_ticket;
|
| }
|
|
|
| @@ -1612,13 +1683,13 @@ ssl3_ServerHandleSessionTicketXtn(sslSocket *ss, PRUint16 ex_type,
|
| hmac_ctx = (HMACContext *)hmac_ctx_buf;
|
| hashObj = HASH_GetRawHashObject(HASH_AlgSHA256);
|
| if (HMAC_Init(hmac_ctx, hashObj, mac_key,
|
| - sizeof(session_ticket_mac_key), PR_FALSE) != SECSuccess)
|
| + sizeof(session_ticket_mac_key), PR_FALSE) != SECSuccess)
|
| goto no_ticket;
|
| HMAC_Begin(hmac_ctx);
|
| HMAC_Update(hmac_ctx, extension_data.data,
|
| - extension_data.len - TLS_EX_SESS_TICKET_MAC_LENGTH);
|
| + extension_data.len - TLS_EX_SESS_TICKET_MAC_LENGTH);
|
| if (HMAC_Finish(hmac_ctx, computed_mac, &computed_mac_length,
|
| - sizeof(computed_mac)) != SECSuccess)
|
| + sizeof(computed_mac)) != SECSuccess)
|
| goto no_ticket;
|
| } else
|
| #endif
|
| @@ -1627,32 +1698,34 @@ ssl3_ServerHandleSessionTicketXtn(sslSocket *ss, PRUint16 ex_type,
|
| macParam.data = NULL;
|
| macParam.len = 0;
|
| hmac_ctx_pkcs11 = PK11_CreateContextBySymKey(macMech,
|
| - CKA_SIGN, mac_key_pkcs11, &macParam);
|
| + CKA_SIGN, mac_key_pkcs11, &macParam);
|
| if (!hmac_ctx_pkcs11) {
|
| SSL_DBG(("%d: SSL[%d]: Unable to create HMAC context: %d.",
|
| - SSL_GETPID(), ss->fd, PORT_GetError()));
|
| + SSL_GETPID(), ss->fd, PORT_GetError()));
|
| goto no_ticket;
|
| } else {
|
| SSL_DBG(("%d: SSL[%d]: Successfully created HMAC context.",
|
| - SSL_GETPID(), ss->fd));
|
| + SSL_GETPID(), ss->fd));
|
| }
|
| rv = PK11_DigestBegin(hmac_ctx_pkcs11);
|
| rv = PK11_DigestOp(hmac_ctx_pkcs11, extension_data.data,
|
| - extension_data.len - TLS_EX_SESS_TICKET_MAC_LENGTH);
|
| + extension_data.len -
|
| + TLS_EX_SESS_TICKET_MAC_LENGTH);
|
| if (rv != SECSuccess) {
|
| PK11_DestroyContext(hmac_ctx_pkcs11, PR_TRUE);
|
| goto no_ticket;
|
| }
|
| rv = PK11_DigestFinal(hmac_ctx_pkcs11, computed_mac,
|
| - &computed_mac_length, sizeof(computed_mac));
|
| + &computed_mac_length, sizeof(computed_mac));
|
| PK11_DestroyContext(hmac_ctx_pkcs11, PR_TRUE);
|
| if (rv != SECSuccess)
|
| goto no_ticket;
|
| }
|
| if (NSS_SecureMemcmp(computed_mac, enc_session_ticket.mac,
|
| - computed_mac_length) != 0) {
|
| + computed_mac_length) !=
|
| + 0) {
|
| SSL_DBG(("%d: SSL[%d]: Session ticket MAC mismatch.",
|
| - SSL_GETPID(), ss->fd));
|
| + SSL_GETPID(), ss->fd));
|
| goto no_ticket;
|
| }
|
|
|
| @@ -1664,24 +1737,24 @@ ssl3_ServerHandleSessionTicketXtn(sslSocket *ss, PRUint16 ex_type,
|
|
|
| /* Plaintext is shorter than the ciphertext due to padding. */
|
| decrypted_state = SECITEM_AllocItem(NULL, NULL,
|
| - enc_session_ticket.encrypted_state.len);
|
| + enc_session_ticket.encrypted_state.len);
|
|
|
| #ifndef NO_PKCS11_BYPASS
|
| if (ss->opt.bypassPKCS11) {
|
| aes_ctx = (AESContext *)aes_ctx_buf;
|
| rv = AES_InitContext(aes_ctx, aes_key,
|
| - sizeof(session_ticket_enc_key), enc_session_ticket.iv,
|
| - NSS_AES_CBC, 0,AES_BLOCK_SIZE);
|
| + sizeof(session_ticket_enc_key), enc_session_ticket.iv,
|
| + NSS_AES_CBC, 0, AES_BLOCK_SIZE);
|
| if (rv != SECSuccess) {
|
| SSL_DBG(("%d: SSL[%d]: Unable to create AES context.",
|
| - SSL_GETPID(), ss->fd));
|
| + SSL_GETPID(), ss->fd));
|
| goto no_ticket;
|
| }
|
|
|
| rv = AES_Decrypt(aes_ctx, decrypted_state->data,
|
| - &decrypted_state->len, decrypted_state->len,
|
| - enc_session_ticket.encrypted_state.data,
|
| - enc_session_ticket.encrypted_state.len);
|
| + &decrypted_state->len, decrypted_state->len,
|
| + enc_session_ticket.encrypted_state.data,
|
| + enc_session_ticket.encrypted_state.len);
|
| if (rv != SECSuccess)
|
| goto no_ticket;
|
| } else
|
| @@ -1691,17 +1764,17 @@ ssl3_ServerHandleSessionTicketXtn(sslSocket *ss, PRUint16 ex_type,
|
| ivItem.data = enc_session_ticket.iv;
|
| ivItem.len = AES_BLOCK_SIZE;
|
| aes_ctx_pkcs11 = PK11_CreateContextBySymKey(cipherMech,
|
| - CKA_DECRYPT, aes_key_pkcs11, &ivItem);
|
| + CKA_DECRYPT, aes_key_pkcs11, &ivItem);
|
| if (!aes_ctx_pkcs11) {
|
| SSL_DBG(("%d: SSL[%d]: Unable to create AES context.",
|
| - SSL_GETPID(), ss->fd));
|
| + SSL_GETPID(), ss->fd));
|
| goto no_ticket;
|
| }
|
|
|
| rv = PK11_CipherOp(aes_ctx_pkcs11, decrypted_state->data,
|
| - (int *)&decrypted_state->len, decrypted_state->len,
|
| - enc_session_ticket.encrypted_state.data,
|
| - enc_session_ticket.encrypted_state.len);
|
| + (int *)&decrypted_state->len, decrypted_state->len,
|
| + enc_session_ticket.encrypted_state.data,
|
| + enc_session_ticket.encrypted_state.len);
|
| PK11_Finalize(aes_ctx_pkcs11);
|
| PK11_DestroyContext(aes_ctx_pkcs11, PR_TRUE);
|
| if (rv != SECSuccess)
|
| @@ -1732,65 +1805,77 @@ ssl3_ServerHandleSessionTicketXtn(sslSocket *ss, PRUint16 ex_type,
|
|
|
| /* Read ticket_version and reject if the version is wrong */
|
| temp = ssl3_ConsumeHandshakeNumber(ss, 2, &buffer, &buffer_len);
|
| - if (temp != TLS_EX_SESS_TICKET_VERSION) goto no_ticket;
|
| + 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);
|
| - if (temp < 0) goto no_ticket;
|
| + if (temp < 0)
|
| + goto no_ticket;
|
| parsed_session_ticket->ssl_version = (SSL3ProtocolVersion)temp;
|
|
|
| /* Read cipher_suite. */
|
| - temp = ssl3_ConsumeHandshakeNumber(ss, 2, &buffer, &buffer_len);
|
| - if (temp < 0) goto no_ticket;
|
| + temp = ssl3_ConsumeHandshakeNumber(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);
|
| - if (temp < 0) goto no_ticket;
|
| + 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);
|
| - if (temp < 0) goto no_ticket;
|
| + if (temp < 0)
|
| + goto no_ticket;
|
| parsed_session_ticket->authAlgorithm = (SSLSignType)temp;
|
| temp = ssl3_ConsumeHandshakeNumber(ss, 4, &buffer, &buffer_len);
|
| - if (temp < 0) goto no_ticket;
|
| + if (temp < 0)
|
| + goto no_ticket;
|
| parsed_session_ticket->authKeyBits = (PRUint32)temp;
|
| temp = ssl3_ConsumeHandshakeNumber(ss, 1, &buffer, &buffer_len);
|
| - if (temp < 0) goto no_ticket;
|
| + if (temp < 0)
|
| + goto no_ticket;
|
| parsed_session_ticket->keaType = (SSLKEAType)temp;
|
| temp = ssl3_ConsumeHandshakeNumber(ss, 4, &buffer, &buffer_len);
|
| - if (temp < 0) goto no_ticket;
|
| + if (temp < 0)
|
| + goto no_ticket;
|
| parsed_session_ticket->keaKeyBits = (PRUint32)temp;
|
|
|
| /* Read wrapped master_secret. */
|
| temp = ssl3_ConsumeHandshakeNumber(ss, 1, &buffer, &buffer_len);
|
| - if (temp < 0) goto no_ticket;
|
| + if (temp < 0)
|
| + goto no_ticket;
|
| parsed_session_ticket->ms_is_wrapped = (PRBool)temp;
|
|
|
| temp = ssl3_ConsumeHandshakeNumber(ss, 1, &buffer, &buffer_len);
|
| - if (temp < 0) goto no_ticket;
|
| + if (temp < 0)
|
| + goto no_ticket;
|
| parsed_session_ticket->exchKeyType = (SSL3KEAType)temp;
|
|
|
| temp = ssl3_ConsumeHandshakeNumber(ss, 4, &buffer, &buffer_len);
|
| - if (temp < 0) goto no_ticket;
|
| + if (temp < 0)
|
| + goto no_ticket;
|
| parsed_session_ticket->msWrapMech = (CK_MECHANISM_TYPE)temp;
|
|
|
| temp = ssl3_ConsumeHandshakeNumber(ss, 2, &buffer, &buffer_len);
|
| - if (temp < 0) goto no_ticket;
|
| + if (temp < 0)
|
| + goto no_ticket;
|
| parsed_session_ticket->ms_length = (PRUint16)temp;
|
| - if (parsed_session_ticket->ms_length == 0 || /* sanity check MS. */
|
| + if (parsed_session_ticket->ms_length == 0 || /* sanity check MS. */
|
| parsed_session_ticket->ms_length >
|
| - sizeof(parsed_session_ticket->master_secret))
|
| + sizeof(parsed_session_ticket->master_secret))
|
| goto no_ticket;
|
|
|
| /* Allow for the wrapped master secret to be longer. */
|
| if (buffer_len < parsed_session_ticket->ms_length)
|
| goto no_ticket;
|
| PORT_Memcpy(parsed_session_ticket->master_secret, buffer,
|
| - parsed_session_ticket->ms_length);
|
| + parsed_session_ticket->ms_length);
|
| buffer += parsed_session_ticket->ms_length;
|
| buffer_len -= parsed_session_ticket->ms_length;
|
|
|
| @@ -1800,16 +1885,18 @@ ssl3_ServerHandleSessionTicketXtn(sslSocket *ss, PRUint16 ex_type,
|
| goto no_ticket;
|
| parsed_session_ticket->client_identity.client_auth_type =
|
| (ClientAuthenticationType)temp;
|
| - switch(parsed_session_ticket->client_identity.client_auth_type) {
|
| + switch (parsed_session_ticket->client_identity.client_auth_type) {
|
| case CLIENT_AUTH_ANONYMOUS:
|
| break;
|
| case CLIENT_AUTH_CERTIFICATE:
|
| rv = ssl3_ConsumeHandshakeVariable(ss, &cert_item, 3,
|
| - &buffer, &buffer_len);
|
| - if (rv != SECSuccess) goto no_ticket;
|
| + &buffer, &buffer_len);
|
| + if (rv != SECSuccess)
|
| + goto no_ticket;
|
| rv = SECITEM_CopyItem(NULL, &parsed_session_ticket->peer_cert,
|
| - &cert_item);
|
| - if (rv != SECSuccess) goto no_ticket;
|
| + &cert_item);
|
| + if (rv != SECSuccess)
|
| + goto no_ticket;
|
| break;
|
| default:
|
| goto no_ticket;
|
| @@ -1822,15 +1909,17 @@ ssl3_ServerHandleSessionTicketXtn(sslSocket *ss, PRUint16 ex_type,
|
|
|
| /* Read server name */
|
| nameType =
|
| - ssl3_ConsumeHandshakeNumber(ss, 1, &buffer, &buffer_len);
|
| + ssl3_ConsumeHandshakeNumber(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);
|
| - if (rv != SECSuccess) goto no_ticket;
|
| + if (rv != SECSuccess)
|
| + goto no_ticket;
|
| rv = SECITEM_CopyItem(NULL, &parsed_session_ticket->srvName,
|
| &name_item);
|
| - if (rv != SECSuccess) goto no_ticket;
|
| + if (rv != SECSuccess)
|
| + goto no_ticket;
|
| parsed_session_ticket->srvName.type = nameType;
|
| }
|
|
|
| @@ -1850,7 +1939,8 @@ ssl3_ServerHandleSessionTicketXtn(sslSocket *ss, PRUint16 ex_type,
|
| */
|
| if (parsed_session_ticket->timestamp != 0 &&
|
| parsed_session_ticket->timestamp +
|
| - TLS_EX_SESS_TICKET_LIFETIME_HINT > ssl_Time()) {
|
| + TLS_EX_SESS_TICKET_LIFETIME_HINT >
|
| + ssl_Time()) {
|
|
|
| sid = ssl3_NewSessionID(ss, PR_TRUE);
|
| if (sid == NULL) {
|
| @@ -1867,35 +1957,34 @@ ssl3_ServerHandleSessionTicketXtn(sslSocket *ss, PRUint16 ex_type,
|
| sid->keaType = parsed_session_ticket->keaType;
|
| sid->keaKeyBits = parsed_session_ticket->keaKeyBits;
|
|
|
| - /* Copy master secret. */
|
| +/* Copy master secret. */
|
| #ifndef NO_PKCS11_BYPASS
|
| if (ss->opt.bypassPKCS11 &&
|
| - parsed_session_ticket->ms_is_wrapped)
|
| + parsed_session_ticket->ms_is_wrapped)
|
| goto no_ticket;
|
| #endif
|
| if (parsed_session_ticket->ms_length >
|
| - sizeof(sid->u.ssl3.keys.wrapped_master_secret))
|
| + sizeof(sid->u.ssl3.keys.wrapped_master_secret))
|
| goto no_ticket;
|
| PORT_Memcpy(sid->u.ssl3.keys.wrapped_master_secret,
|
| - parsed_session_ticket->master_secret,
|
| - parsed_session_ticket->ms_length);
|
| + parsed_session_ticket->master_secret,
|
| + parsed_session_ticket->ms_length);
|
| sid->u.ssl3.keys.wrapped_master_secret_len =
|
| parsed_session_ticket->ms_length;
|
| sid->u.ssl3.exchKeyType = parsed_session_ticket->exchKeyType;
|
| sid->u.ssl3.masterWrapMech = parsed_session_ticket->msWrapMech;
|
| sid->u.ssl3.keys.msIsWrapped =
|
| parsed_session_ticket->ms_is_wrapped;
|
| - sid->u.ssl3.masterValid = PR_TRUE;
|
| + sid->u.ssl3.masterValid = PR_TRUE;
|
| sid->u.ssl3.keys.resumable = PR_TRUE;
|
| - sid->u.ssl3.keys.extendedMasterSecretUsed = parsed_session_ticket->
|
| - extendedMasterSecretUsed;
|
| + sid->u.ssl3.keys.extendedMasterSecretUsed = parsed_session_ticket->extendedMasterSecretUsed;
|
|
|
| /* Copy over client cert from session ticket if there is one. */
|
| if (parsed_session_ticket->peer_cert.data != NULL) {
|
| if (sid->peerCert != NULL)
|
| CERT_DestroyCertificate(sid->peerCert);
|
| sid->peerCert = CERT_NewTempCertificate(ss->dbHandle,
|
| - &parsed_session_ticket->peer_cert, NULL, PR_FALSE, PR_TRUE);
|
| + &parsed_session_ticket->peer_cert, NULL, PR_FALSE, PR_TRUE);
|
| if (sid->peerCert == NULL) {
|
| rv = SECFailure;
|
| goto loser;
|
| @@ -1910,22 +1999,22 @@ ssl3_ServerHandleSessionTicketXtn(sslSocket *ss, PRUint16 ex_type,
|
| }
|
|
|
| if (0) {
|
| -no_ticket:
|
| + no_ticket:
|
| SSL_DBG(("%d: SSL[%d]: Session ticket parsing failed.",
|
| - SSL_GETPID(), ss->fd));
|
| + SSL_GETPID(), ss->fd));
|
| ssl3stats = SSL_GetStatistics();
|
| - SSL_AtomicIncrementLong(& ssl3stats->hch_sid_ticket_parse_failures );
|
| + SSL_AtomicIncrementLong(&ssl3stats->hch_sid_ticket_parse_failures);
|
| }
|
| rv = SECSuccess;
|
|
|
| loser:
|
| - /* ss->sec.ci.sid == sid if it did NOT come here via goto statement
|
| - * in that case do not free sid
|
| - */
|
| - if (sid && (ss->sec.ci.sid != sid)) {
|
| - ssl_FreeSID(sid);
|
| - sid = NULL;
|
| - }
|
| + /* ss->sec.ci.sid == sid if it did NOT come here via goto statement
|
| + * in that case do not free sid
|
| + */
|
| + if (sid && (ss->sec.ci.sid != sid)) {
|
| + ssl_FreeSID(sid);
|
| + sid = NULL;
|
| + }
|
| if (decrypted_state != NULL) {
|
| SECITEM_FreeItem(decrypted_state, PR_TRUE);
|
| decrypted_state = NULL;
|
| @@ -1963,18 +2052,22 @@ ssl3_ParseEncryptedSessionTicket(sslSocket *ss, SECItem *data,
|
| EncryptedSessionTicket *enc_session_ticket)
|
| {
|
| if (ssl3_ConsumeFromItem(data, &enc_session_ticket->key_name,
|
| - SESS_TICKET_KEY_NAME_LEN) != SECSuccess)
|
| + SESS_TICKET_KEY_NAME_LEN) !=
|
| + SECSuccess)
|
| return SECFailure;
|
| if (ssl3_ConsumeFromItem(data, &enc_session_ticket->iv,
|
| - AES_BLOCK_SIZE) != SECSuccess)
|
| + AES_BLOCK_SIZE) !=
|
| + SECSuccess)
|
| return SECFailure;
|
| if (ssl3_ConsumeHandshakeVariable(ss, &enc_session_ticket->encrypted_state,
|
| - 2, &data->data, &data->len) != SECSuccess)
|
| + 2, &data->data, &data->len) !=
|
| + SECSuccess)
|
| return SECFailure;
|
| if (ssl3_ConsumeFromItem(data, &enc_session_ticket->mac,
|
| - TLS_EX_SESS_TICKET_MAC_LENGTH) != SECSuccess)
|
| + TLS_EX_SESS_TICKET_MAC_LENGTH) !=
|
| + SECSuccess)
|
| return SECFailure;
|
| - if (data->len != 0) /* Make sure that we have consumed all bytes. */
|
| + if (data->len != 0) /* Make sure that we have consumed all bytes. */
|
| return SECFailure;
|
|
|
| return SECSuccess;
|
| @@ -1985,30 +2078,46 @@ ssl3_ParseEncryptedSessionTicket(sslSocket *ss, SECItem *data,
|
| * if present, invoke that handler.
|
| * Servers ignore any extensions with unknown extension types.
|
| * Clients reject any extensions with unadvertised extension types.
|
| + * In TLS >= 1.3, the client checks that extensions appear in the
|
| + * right phase.
|
| */
|
| SECStatus
|
| -ssl3_HandleHelloExtensions(sslSocket *ss, SSL3Opaque **b, PRUint32 *length)
|
| +ssl3_HandleHelloExtensions(sslSocket *ss, SSL3Opaque **b, PRUint32 *length,
|
| + SSL3HandshakeType handshakeMessage)
|
| {
|
| - const ssl3HelloExtensionHandler * handlers;
|
| + const ssl3HelloExtensionHandler *handlers;
|
| + PRBool isTLS13 = ss->version >= SSL_LIBRARY_VERSION_TLS_1_3;
|
|
|
| - if (ss->sec.isServer) {
|
| - handlers = clientHelloHandlers;
|
| - } else if (ss->version > SSL_LIBRARY_VERSION_3_0) {
|
| - handlers = serverHelloHandlersTLS;
|
| - } else {
|
| - handlers = serverHelloHandlersSSL3;
|
| + switch (handshakeMessage) {
|
| + case client_hello:
|
| + handlers = clientHelloHandlers;
|
| + break;
|
| + case encrypted_extensions:
|
| + PORT_Assert(ss->version >= SSL_LIBRARY_VERSION_TLS_1_3);
|
| + /* fall through */
|
| + case server_hello:
|
| + if (ss->version > SSL_LIBRARY_VERSION_3_0) {
|
| + handlers = serverHelloHandlersTLS;
|
| + } else {
|
| + handlers = serverHelloHandlersSSL3;
|
| + }
|
| + break;
|
| + default:
|
| + PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
|
| + PORT_Assert(0);
|
| + return SECFailure;
|
| }
|
|
|
| while (*length) {
|
| - const ssl3HelloExtensionHandler * handler;
|
| + const ssl3HelloExtensionHandler *handler;
|
| SECStatus rv;
|
| - PRInt32 extension_type;
|
| - SECItem extension_data;
|
| + PRInt32 extension_type;
|
| + SECItem extension_data;
|
|
|
| /* Get the extension's type field */
|
| extension_type = ssl3_ConsumeHandshakeNumber(ss, 2, b, length);
|
| - if (extension_type < 0) /* failure to decode extension_type */
|
| - return SECFailure; /* alert already sent */
|
| + if (extension_type < 0) /* failure to decode extension_type */
|
| + return SECFailure; /* alert already sent */
|
|
|
| /* get the data for this extension, so we can pass it or skip it. */
|
| rv = ssl3_ConsumeHandshakeVariable(ss, &extension_data, 2, b, length);
|
| @@ -2016,8 +2125,7 @@ ssl3_HandleHelloExtensions(sslSocket *ss, SSL3Opaque **b, PRUint32 *length)
|
| return rv; /* alert already sent */
|
|
|
| /* Check whether the server sent an extension which was not advertised
|
| - * in the ClientHello.
|
| - */
|
| + * in the ClientHello */
|
| if (!ss->sec.isServer &&
|
| !ssl3_ClientExtensionAdvertised(ss, extension_type)) {
|
| (void)SSL3_SendAlert(ss, alert_fatal, unsupported_extension);
|
| @@ -2030,12 +2138,23 @@ ssl3_HandleHelloExtensions(sslSocket *ss, SSL3Opaque **b, PRUint32 *length)
|
| return SECFailure;
|
| }
|
|
|
| + /* Check that this is a legal extension in TLS 1.3 */
|
| + if (isTLS13 && !tls13_ExtensionAllowed(extension_type, handshakeMessage)) {
|
| + if (handshakeMessage == client_hello) {
|
| + /* Skip extensions not used in TLS 1.3 */
|
| + continue;
|
| + }
|
| + tls13_FatalError(ss, SSL_ERROR_EXTENSION_DISALLOWED_FOR_VERSION,
|
| + unsupported_extension);
|
| + return SECFailure;
|
| + }
|
| +
|
| /* find extension_type in table of Hello Extension Handlers */
|
| for (handler = handlers; handler->ex_type >= 0; handler++) {
|
| /* if found, call this handler */
|
| if (handler->ex_type == extension_type) {
|
| rv = (*handler->ex_handler)(ss, (PRUint16)extension_type,
|
| - &extension_data);
|
| + &extension_data);
|
| if (rv != SECSuccess) {
|
| if (!ss->ssl3.fatalAlertSent) {
|
| /* send a generic alert if the handler didn't already */
|
| @@ -2056,11 +2175,22 @@ ssl3_RegisterServerHelloExtensionSender(sslSocket *ss, PRUint16 ex_type,
|
| ssl3HelloExtensionSenderFunc cb)
|
| {
|
| int i;
|
| - ssl3HelloExtensionSender *sender = &ss->xtnData.serverSenders[0];
|
| + ssl3HelloExtensionSender *sender;
|
| + if (ss->version < SSL_LIBRARY_VERSION_TLS_1_3) {
|
| + sender = &ss->xtnData.serverHelloSenders[0];
|
| + } else {
|
| + if (tls13_ExtensionAllowed(ex_type, server_hello)) {
|
| + PORT_Assert(!tls13_ExtensionAllowed(ex_type, encrypted_extensions));
|
| + sender = &ss->xtnData.serverHelloSenders[0];
|
| + } else {
|
| + PORT_Assert(tls13_ExtensionAllowed(ex_type, encrypted_extensions));
|
| + sender = &ss->xtnData.encryptedExtensionsSenders[0];
|
| + }
|
| + }
|
|
|
| for (i = 0; i < SSL_MAX_EXTENSIONS; ++i, ++sender) {
|
| if (!sender->ex_sender) {
|
| - sender->ex_type = ex_type;
|
| + sender->ex_type = ex_type;
|
| sender->ex_sender = cb;
|
| return SECSuccess;
|
| }
|
| @@ -2085,8 +2215,11 @@ ssl3_CallHelloExtensionSenders(sslSocket *ss, PRBool append, PRUint32 maxBytes,
|
| int i;
|
|
|
| if (!sender) {
|
| - sender = ss->version > SSL_LIBRARY_VERSION_3_0 ?
|
| - &clientHelloSendersTLS[0] : &clientHelloSendersSSL3[0];
|
| + if (ss->version > SSL_LIBRARY_VERSION_3_0) {
|
| + sender = &clientHelloSendersTLS[0];
|
| + } else {
|
| + sender = &clientHelloSendersSSL3[0];
|
| + }
|
| }
|
|
|
| for (i = 0; i < SSL_MAX_EXTENSIONS; ++i, ++sender) {
|
| @@ -2094,14 +2227,13 @@ ssl3_CallHelloExtensionSenders(sslSocket *ss, PRBool append, PRUint32 maxBytes,
|
| PRInt32 extLen = (*sender->ex_sender)(ss, append, maxBytes);
|
| if (extLen < 0)
|
| return -1;
|
| - maxBytes -= extLen;
|
| + maxBytes -= extLen;
|
| total_exten_len += extLen;
|
| }
|
| }
|
| return total_exten_len;
|
| }
|
|
|
| -
|
| /* Extension format:
|
| * Extension number: 2 bytes
|
| * Extension length: 2 bytes
|
| @@ -2111,11 +2243,12 @@ ssl3_CallHelloExtensionSenders(sslSocket *ss, PRBool append, PRUint32 maxBytes,
|
| */
|
| static PRInt32
|
| ssl3_SendRenegotiationInfoXtn(
|
| - sslSocket * ss,
|
| - PRBool append,
|
| - PRUint32 maxBytes)
|
| + sslSocket *ss,
|
| + PRBool append,
|
| + PRUint32 maxBytes)
|
| {
|
| - PRInt32 len, needed;
|
| + PRInt32 len = 0;
|
| + PRInt32 needed;
|
|
|
| /* In draft-ietf-tls-renegotiation-03, it is NOT RECOMMENDED to send
|
| * both the SCSV and the empty RI, so when we send SCSV in
|
| @@ -2123,9 +2256,10 @@ ssl3_SendRenegotiationInfoXtn(
|
| */
|
| if (!ss || ss->ssl3.hs.sendingSCSV)
|
| return 0;
|
| - len = !ss->firstHsDone ? 0 :
|
| - (ss->sec.isServer ? ss->ssl3.hs.finishedBytes * 2
|
| - : ss->ssl3.hs.finishedBytes);
|
| + if (ss->firstHsDone) {
|
| + len = ss->sec.isServer ? ss->ssl3.hs.finishedBytes * 2
|
| + : ss->ssl3.hs.finishedBytes;
|
| + }
|
| needed = 5 + len;
|
| if (maxBytes < (PRUint32)needed) {
|
| return 0;
|
| @@ -2134,18 +2268,21 @@ ssl3_SendRenegotiationInfoXtn(
|
| SECStatus rv;
|
| /* extension_type */
|
| rv = ssl3_AppendHandshakeNumber(ss, ssl_renegotiation_info_xtn, 2);
|
| - if (rv != SECSuccess) return -1;
|
| + if (rv != SECSuccess)
|
| + return -1;
|
| /* length of extension_data */
|
| rv = ssl3_AppendHandshakeNumber(ss, len + 1, 2);
|
| - if (rv != SECSuccess) return -1;
|
| + if (rv != SECSuccess)
|
| + return -1;
|
| /* verify_Data from previous Finished message(s) */
|
| rv = ssl3_AppendHandshakeVariable(ss,
|
| - ss->ssl3.hs.finishedMsgs.data, len, 1);
|
| - if (rv != SECSuccess) return -1;
|
| + 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;
|
| + ssl_renegotiation_info_xtn;
|
| }
|
| }
|
| return needed;
|
| @@ -2162,7 +2299,7 @@ ssl3_ServerHandleStatusRequestXtn(sslSocket *ss, PRUint16 ex_type,
|
| PORT_Assert(ss->sec.isServer);
|
| /* prepare to send back the appropriate response */
|
| rv = ssl3_RegisterServerHelloExtensionSender(ss, ex_type,
|
| - ssl3_ServerSendStatusRequestXtn);
|
| + ssl3_ServerSendStatusRequestXtn);
|
| return rv;
|
| }
|
|
|
| @@ -2177,7 +2314,7 @@ ssl3_HandleRenegotiationInfoXtn(sslSocket *ss, PRUint16 ex_type, SECItem *data)
|
| len = ss->sec.isServer ? ss->ssl3.hs.finishedBytes
|
| : ss->ssl3.hs.finishedBytes * 2;
|
| }
|
| - if (data->len != 1 + len || data->data[0] != len ) {
|
| + if (data->len != 1 + len || data->data[0] != len) {
|
| (void)ssl3_DecodeError(ss);
|
| return SECFailure;
|
| }
|
| @@ -2209,22 +2346,25 @@ ssl3_ClientSendUseSRTPXtn(sslSocket *ss, PRBool append, PRUint32 maxBytes)
|
| return 0;
|
|
|
| if (!IS_DTLS(ss) || !ss->ssl3.dtlsSRTPCipherCount)
|
| - return 0; /* Not relevant */
|
| + return 0; /* Not relevant */
|
|
|
| ext_data_len = 2 + 2 * ss->ssl3.dtlsSRTPCipherCount + 1;
|
|
|
| if (append && maxBytes >= 4 + ext_data_len) {
|
| /* Extension type */
|
| rv = ssl3_AppendHandshakeNumber(ss, ssl_use_srtp_xtn, 2);
|
| - if (rv != SECSuccess) return -1;
|
| + if (rv != SECSuccess)
|
| + return -1;
|
| /* Length of extension data */
|
| rv = ssl3_AppendHandshakeNumber(ss, ext_data_len, 2);
|
| - if (rv != SECSuccess) return -1;
|
| + if (rv != SECSuccess)
|
| + return -1;
|
| /* Length of the SRTP cipher list */
|
| rv = ssl3_AppendHandshakeNumber(ss,
|
| 2 * ss->ssl3.dtlsSRTPCipherCount,
|
| 2);
|
| - if (rv != SECSuccess) return -1;
|
| + if (rv != SECSuccess)
|
| + return -1;
|
| /* The SRTP ciphers */
|
| for (i = 0; i < ss->ssl3.dtlsSRTPCipherCount; i++) {
|
| rv = ssl3_AppendHandshakeNumber(ss,
|
| @@ -2235,7 +2375,7 @@ ssl3_ClientSendUseSRTPXtn(sslSocket *ss, PRBool append, PRUint32 maxBytes)
|
| ssl3_AppendHandshakeVariable(ss, NULL, 0, 1);
|
|
|
| ss->xtnData.advertised[ss->xtnData.numAdvertised++] =
|
| - ssl_use_srtp_xtn;
|
| + ssl_use_srtp_xtn;
|
| }
|
|
|
| return 4 + ext_data_len;
|
| @@ -2253,16 +2393,20 @@ ssl3_ServerSendUseSRTPXtn(sslSocket *ss, PRBool append, PRUint32 maxBytes)
|
|
|
| /* Extension type */
|
| rv = ssl3_AppendHandshakeNumber(ss, ssl_use_srtp_xtn, 2);
|
| - if (rv != SECSuccess) return -1;
|
| + if (rv != SECSuccess)
|
| + return -1;
|
| /* Length of extension data */
|
| rv = ssl3_AppendHandshakeNumber(ss, 5, 2);
|
| - if (rv != SECSuccess) return -1;
|
| + if (rv != SECSuccess)
|
| + return -1;
|
| /* Length of the SRTP cipher list */
|
| rv = ssl3_AppendHandshakeNumber(ss, 2, 2);
|
| - if (rv != SECSuccess) return -1;
|
| + if (rv != SECSuccess)
|
| + return -1;
|
| /* The selected cipher */
|
| rv = ssl3_AppendHandshakeNumber(ss, ss->ssl3.dtlsSRTPCipherSuite, 2);
|
| - if (rv != SECSuccess) return -1;
|
| + if (rv != SECSuccess)
|
| + return -1;
|
| /* Empty MKI value */
|
| ssl3_AppendHandshakeVariable(ss, NULL, 0, 1);
|
|
|
| @@ -2270,10 +2414,10 @@ ssl3_ServerSendUseSRTPXtn(sslSocket *ss, PRBool append, PRUint32 maxBytes)
|
| }
|
|
|
| static SECStatus
|
| -ssl3_ClientHandleUseSRTPXtn(sslSocket * ss, PRUint16 ex_type, SECItem *data)
|
| +ssl3_ClientHandleUseSRTPXtn(sslSocket *ss, PRUint16 ex_type, SECItem *data)
|
| {
|
| SECStatus rv;
|
| - SECItem ciphers = {siBuffer, NULL, 0};
|
| + SECItem ciphers = { siBuffer, NULL, 0 };
|
| PRUint16 i;
|
| PRUint16 cipher = 0;
|
| PRBool found = PR_FALSE;
|
| @@ -2288,7 +2432,7 @@ ssl3_ClientHandleUseSRTPXtn(sslSocket * ss, PRUint16 ex_type, SECItem *data)
|
| rv = ssl3_ConsumeHandshakeVariable(ss, &ciphers, 2,
|
| &data->data, &data->len);
|
| if (rv != SECSuccess) {
|
| - return SECFailure; /* fatal alert already sent */
|
| + return SECFailure; /* fatal alert already sent */
|
| }
|
| /* Now check that the server has picked just 1 (i.e., len = 2) */
|
| if (ciphers.len != 2) {
|
| @@ -2340,10 +2484,10 @@ ssl3_ClientHandleUseSRTPXtn(sslSocket * ss, PRUint16 ex_type, SECItem *data)
|
| }
|
|
|
| static SECStatus
|
| -ssl3_ServerHandleUseSRTPXtn(sslSocket * ss, PRUint16 ex_type, SECItem *data)
|
| +ssl3_ServerHandleUseSRTPXtn(sslSocket *ss, PRUint16 ex_type, SECItem *data)
|
| {
|
| SECStatus rv;
|
| - SECItem ciphers = {siBuffer, NULL, 0};
|
| + SECItem ciphers = { siBuffer, NULL, 0 };
|
| PRUint16 i;
|
| unsigned int j;
|
| PRUint16 cipher = 0;
|
| @@ -2414,7 +2558,7 @@ ssl3_ServerHandleUseSRTPXtn(sslSocket * ss, PRUint16 ex_type, SECItem *data)
|
| * from a client.
|
| * See https://tools.ietf.org/html/rfc5246#section-7.4.1.4.1 */
|
| static SECStatus
|
| -ssl3_ServerHandleSigAlgsXtn(sslSocket * ss, PRUint16 ex_type, SECItem *data)
|
| +ssl3_ServerHandleSigAlgsXtn(sslSocket *ss, PRUint16 ex_type, SECItem *data)
|
| {
|
| SECStatus rv;
|
| SECItem algorithms;
|
| @@ -2438,7 +2582,7 @@ ssl3_ServerHandleSigAlgsXtn(sslSocket * ss, PRUint16 ex_type, SECItem *data)
|
| return SECFailure;
|
| }
|
|
|
| - numAlgorithms = algorithms.len/2;
|
| + numAlgorithms = algorithms.len / 2;
|
|
|
| /* We don't care to process excessive numbers of algorithms. */
|
| if (numAlgorithms > 512) {
|
| @@ -2446,7 +2590,7 @@ ssl3_ServerHandleSigAlgsXtn(sslSocket * ss, PRUint16 ex_type, SECItem *data)
|
| }
|
|
|
| ss->ssl3.hs.clientSigAndHash =
|
| - PORT_NewArray(SSLSignatureAndHashAlg, numAlgorithms);
|
| + PORT_NewArray(SSLSignatureAndHashAlg, numAlgorithms);
|
| if (!ss->ssl3.hs.clientSigAndHash) {
|
| (void)SSL3_SendAlert(ss, alert_fatal, internal_error);
|
| PORT_SetError(SSL_ERROR_RX_MALFORMED_CLIENT_HELLO);
|
| @@ -2459,8 +2603,8 @@ ssl3_ServerHandleSigAlgsXtn(sslSocket * ss, PRUint16 ex_type, SECItem *data)
|
| for (i = 0; i < numAlgorithms; i++) {
|
| SSLSignatureAndHashAlg *sigAndHash =
|
| &ss->ssl3.hs.clientSigAndHash[ss->ssl3.hs.numClientSigAndHash];
|
| - sigAndHash->hashAlg = (SSLHashType)*(b++);
|
| - sigAndHash->sigAlg = (SSLSignType)*(b++);
|
| + sigAndHash->hashAlg = (SSLHashType) * (b++);
|
| + sigAndHash->sigAlg = (SSLSignType) * (b++);
|
| if (ssl3_IsSupportedSignatureAlgorithm(sigAndHash)) {
|
| ++ss->ssl3.hs.numClientSigAndHash;
|
| }
|
| @@ -2485,7 +2629,7 @@ ssl3_ClientSendSigAlgsXtn(sslSocket *ss, PRBool append, PRUint32 maxBytes)
|
| {
|
| PRInt32 extension_length;
|
| unsigned int i;
|
| - PRInt32 pos=0;
|
| + PRInt32 pos = 0;
|
| PRUint32 policy;
|
| PRUint8 buf[MAX_SIGNATURE_ALGORITHMS * 2];
|
|
|
| @@ -2493,14 +2637,14 @@ ssl3_ClientSendSigAlgsXtn(sslSocket *ss, PRBool append, PRUint32 maxBytes)
|
| return 0;
|
| }
|
|
|
| - for (i=0; i < ss->ssl3.signatureAlgorithmCount; i++) {
|
| - SECOidTag hashOID = ssl3_TLSHashAlgorithmToOID(
|
| - ss->ssl3.signatureAlgorithms[i].hashAlg);
|
| - if ((NSS_GetAlgorithmPolicy(hashOID, & policy) != SECSuccess) ||
|
| - (policy & NSS_USE_ALG_IN_SSL_KX)) {
|
| - buf[pos++] = ss->ssl3.signatureAlgorithms[i].hashAlg;
|
| - buf[pos++] = ss->ssl3.signatureAlgorithms[i].sigAlg;
|
| - }
|
| + for (i = 0; i < ss->ssl3.signatureAlgorithmCount; i++) {
|
| + SECOidTag hashOID = ssl3_TLSHashAlgorithmToOID(
|
| + ss->ssl3.signatureAlgorithms[i].hashAlg);
|
| + if ((NSS_GetAlgorithmPolicy(hashOID, &policy) != SECSuccess) ||
|
| + (policy & NSS_USE_ALG_IN_SSL_KX)) {
|
| + buf[pos++] = ss->ssl3.signatureAlgorithms[i].hashAlg;
|
| + buf[pos++] = ss->ssl3.signatureAlgorithms[i].sigAlg;
|
| + }
|
| }
|
|
|
| extension_length =
|
| @@ -2531,7 +2675,7 @@ ssl3_ClientSendSigAlgsXtn(sslSocket *ss, PRBool append, PRUint32 maxBytes)
|
| }
|
|
|
| ss->xtnData.advertised[ss->xtnData.numAdvertised++] =
|
| - ssl_signature_algorithms_xtn;
|
| + ssl_signature_algorithms_xtn;
|
| }
|
|
|
| return extension_length;
|
| @@ -2595,7 +2739,7 @@ ssl3_AppendPaddingExtension(sslSocket *ss, unsigned int extensionLen,
|
| * version extension.
|
| * TODO(ekr@rtfm.com): Remove when TLS 1.3 is published. */
|
| static PRInt32
|
| -ssl3_ClientSendDraftVersionXtn(sslSocket * ss, PRBool append, PRUint32 maxBytes)
|
| +ssl3_ClientSendDraftVersionXtn(sslSocket *ss, PRBool append, PRUint32 maxBytes)
|
| {
|
| PRInt32 extension_length;
|
|
|
| @@ -2603,7 +2747,7 @@ ssl3_ClientSendDraftVersionXtn(sslSocket * ss, PRBool append, PRUint32 maxBytes)
|
| return 0;
|
| }
|
|
|
| - extension_length = 6; /* Type + length + number */
|
| + extension_length = 6; /* Type + length + number */
|
| if (maxBytes < (PRUint32)extension_length) {
|
| PORT_Assert(0);
|
| return 0;
|
| @@ -2620,7 +2764,7 @@ ssl3_ClientSendDraftVersionXtn(sslSocket * ss, PRBool append, PRUint32 maxBytes)
|
| if (rv != SECSuccess)
|
| goto loser;
|
| ss->xtnData.advertised[ss->xtnData.numAdvertised++] =
|
| - ssl_tls13_draft_version_xtn;
|
| + ssl_tls13_draft_version_xtn;
|
| }
|
|
|
| return extension_length;
|
| @@ -2633,7 +2777,7 @@ loser:
|
| * version extension.
|
| * TODO(ekr@rtfm.com): Remove when TLS 1.3 is published. */
|
| static SECStatus
|
| -ssl3_ServerHandleDraftVersionXtn(sslSocket * ss, PRUint16 ex_type,
|
| +ssl3_ServerHandleDraftVersionXtn(sslSocket *ss, PRUint16 ex_type,
|
| SECItem *data)
|
| {
|
| PRInt32 draft_version;
|
| @@ -2674,7 +2818,7 @@ ssl3_ServerHandleDraftVersionXtn(sslSocket * ss, PRUint16 ex_type,
|
| }
|
|
|
| static PRInt32
|
| -ssl3_SendExtendedMasterSecretXtn(sslSocket * ss, PRBool append,
|
| +ssl3_SendExtendedMasterSecretXtn(sslSocket *ss, PRBool append,
|
| PRUint32 maxBytes)
|
| {
|
| PRInt32 extension_length;
|
| @@ -2695,7 +2839,7 @@ ssl3_SendExtendedMasterSecretXtn(sslSocket * ss, PRBool append,
|
| /* Always send the extension in this function, since the
|
| * client always sends it and this function is only called on
|
| * the server if we negotiated the extension. */
|
| - extension_length = 4; /* Type + length (0) */
|
| + extension_length = 4; /* Type + length (0) */
|
| if (maxBytes < extension_length) {
|
| PORT_Assert(0);
|
| return 0;
|
| @@ -2710,56 +2854,18 @@ ssl3_SendExtendedMasterSecretXtn(sslSocket * ss, PRBool append,
|
| if (rv != SECSuccess)
|
| goto loser;
|
| ss->xtnData.advertised[ss->xtnData.numAdvertised++] =
|
| - ssl_extended_master_secret_xtn;
|
| + ssl_extended_master_secret_xtn;
|
| }
|
|
|
| return extension_length;
|
| +
|
| loser:
|
| return -1;
|
| }
|
|
|
| -/* ssl3_ClientSendSignedCertTimestampXtn sends the signed_certificate_timestamp
|
| - * extension for TLS ClientHellos. */
|
| -static PRInt32
|
| -ssl3_ClientSendSignedCertTimestampXtn(sslSocket *ss, PRBool append,
|
| - PRUint32 maxBytes)
|
| -{
|
| - PRInt32 extension_length = 2 /* extension_type */ +
|
| - 2 /* length(extension_data) */;
|
| -
|
| - /* Only send the extension if processing is enabled. */
|
| - if (!ss->opt.enableSignedCertTimestamps)
|
| - return 0;
|
| -
|
| - if (maxBytes < extension_length) {
|
| - PORT_Assert(0);
|
| - return 0;
|
| - }
|
| -
|
| - if (append) {
|
| - SECStatus rv;
|
| - /* extension_type */
|
| - rv = ssl3_AppendHandshakeNumber(ss,
|
| - ssl_signed_certificate_timestamp_xtn,
|
| - 2);
|
| - if (rv != SECSuccess)
|
| - goto loser;
|
| - /* zero length */
|
| - rv = ssl3_AppendHandshakeNumber(ss, 0, 2);
|
| - if (rv != SECSuccess)
|
| - goto loser;
|
| - ss->xtnData.advertised[ss->xtnData.numAdvertised++] =
|
| - ssl_signed_certificate_timestamp_xtn;
|
| - }
|
| -
|
| - return extension_length;
|
| -loser:
|
| - return -1;
|
| -}
|
| -
|
| -static SECStatus
|
| -ssl3_HandleExtendedMasterSecretXtn(sslSocket * ss, PRUint16 ex_type,
|
| - SECItem *data)
|
| +static SECStatus
|
| +ssl3_HandleExtendedMasterSecretXtn(sslSocket *ss, PRUint16 ex_type,
|
| + SECItem *data)
|
| {
|
| if (ss->version < SSL_LIBRARY_VERSION_TLS_1_0) {
|
| return SECSuccess;
|
| @@ -2797,6 +2903,43 @@ ssl3_HandleExtendedMasterSecretXtn(sslSocket * ss, PRUint16 ex_type,
|
| return SECSuccess;
|
| }
|
|
|
| +/* ssl3_ClientSendSignedCertTimestampXtn sends the signed_certificate_timestamp
|
| + * extension for TLS ClientHellos. */
|
| +static PRInt32
|
| +ssl3_ClientSendSignedCertTimestampXtn(sslSocket *ss, PRBool append,
|
| + PRUint32 maxBytes)
|
| +{
|
| + PRInt32 extension_length = 2 /* extension_type */ +
|
| + 2 /* length(extension_data) */;
|
| +
|
| + /* Only send the extension if processing is enabled. */
|
| + if (!ss->opt.enableSignedCertTimestamps)
|
| + return 0;
|
| +
|
| + if (append && maxBytes >= extension_length) {
|
| + SECStatus rv;
|
| + /* extension_type */
|
| + rv = ssl3_AppendHandshakeNumber(ss,
|
| + ssl_signed_cert_timestamp_xtn,
|
| + 2);
|
| + if (rv != SECSuccess)
|
| + goto loser;
|
| + /* zero length */
|
| + rv = ssl3_AppendHandshakeNumber(ss, 0, 2);
|
| + if (rv != SECSuccess)
|
| + goto loser;
|
| + ss->xtnData.advertised[ss->xtnData.numAdvertised++] =
|
| + ssl_signed_cert_timestamp_xtn;
|
| + } else if (maxBytes < extension_length) {
|
| + PORT_Assert(0);
|
| + return 0;
|
| + }
|
| +
|
| + return extension_length;
|
| +loser:
|
| + return -1;
|
| +}
|
| +
|
| static SECStatus
|
| ssl3_ClientHandleSignedCertTimestampXtn(sslSocket *ss, PRUint16 ex_type,
|
| SECItem *data)
|
| @@ -2821,3 +2964,327 @@ ssl3_ClientHandleSignedCertTimestampXtn(sslSocket *ss, PRUint16 ex_type,
|
| ss->xtnData.negotiated[ss->xtnData.numNegotiated++] = ex_type;
|
| return SECSuccess;
|
| }
|
| +
|
| +static PRInt32
|
| +ssl3_ServerSendSignedCertTimestampXtn(sslSocket *ss,
|
| + PRBool append,
|
| + PRUint32 maxBytes)
|
| +{
|
| + PRInt32 extension_length;
|
| + SSLKEAType effectiveExchKeyType;
|
| + const SECItem *scts;
|
| +
|
| + if (ss->ssl3.hs.kea_def->kea == kea_ecdhe_rsa ||
|
| + ss->ssl3.hs.kea_def->kea == kea_dhe_rsa) {
|
| + effectiveExchKeyType = ssl_kea_rsa;
|
| + } else {
|
| + effectiveExchKeyType = ss->ssl3.hs.kea_def->exchKeyType;
|
| + }
|
| +
|
| + scts = &ss->signedCertTimestamps[effectiveExchKeyType];
|
| +
|
| + if (!scts->len) {
|
| + /* No timestamps to send */
|
| + return 0;
|
| + }
|
| +
|
| + extension_length = 2 /* extension_type */ +
|
| + 2 /* length(extension_data) */ +
|
| + scts->len;
|
| +
|
| + if (maxBytes < extension_length) {
|
| + PORT_Assert(0);
|
| + return 0;
|
| + }
|
| + if (append) {
|
| + SECStatus rv;
|
| + /* extension_type */
|
| + rv = ssl3_AppendHandshakeNumber(ss,
|
| + ssl_signed_cert_timestamp_xtn,
|
| + 2);
|
| + if (rv != SECSuccess)
|
| + goto loser;
|
| + /* extension_data */
|
| + rv = ssl3_AppendHandshakeVariable(ss, scts->data, scts->len, 2);
|
| + if (rv != SECSuccess)
|
| + goto loser;
|
| + }
|
| +
|
| + return extension_length;
|
| +
|
| +loser:
|
| + return -1;
|
| +}
|
| +
|
| +static SECStatus
|
| +ssl3_ServerHandleSignedCertTimestampXtn(sslSocket *ss, PRUint16 ex_type,
|
| + SECItem *data)
|
| +{
|
| + ss->xtnData.negotiated[ss->xtnData.numNegotiated++] = ex_type;
|
| + PORT_Assert(ss->sec.isServer);
|
| + return ssl3_RegisterServerHelloExtensionSender(ss, ex_type,
|
| + ssl3_ServerSendSignedCertTimestampXtn);
|
| +}
|
| +
|
| +/*
|
| + * [draft-ietf-tls-tls13-11] Section 6.3.2.3.
|
| + *
|
| + * struct {
|
| + * NamedGroup group;
|
| + * opaque key_exchange<1..2^16-1>;
|
| + * } KeyShareEntry;
|
| + *
|
| + * struct {
|
| + * select (role) {
|
| + * case client:
|
| + * KeyShareEntry client_shares<4..2^16-1>;
|
| + *
|
| + * case server:
|
| + * KeyShareEntry server_share;
|
| + * }
|
| + * } KeyShare;
|
| + */
|
| +static SECStatus
|
| +tls13_SizeOfKeyShareEntry(ssl3KeyPair *pair)
|
| +{
|
| + return 2 + 2 + tls13_SizeOfECDHEKeyShareKEX(pair);
|
| +}
|
| +
|
| +static SECStatus
|
| +tls13_EncodeKeyShareEntry(sslSocket *ss, ssl3KeyPair *pair)
|
| +{
|
| + SECStatus rv;
|
| +
|
| + /* This currently only works for ECC keys */
|
| + PORT_Assert(pair->pubKey->keyType == ecKey);
|
| + if (pair->pubKey->keyType != ecKey) {
|
| + PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
|
| + return SECFailure;
|
| + }
|
| +
|
| + rv = ssl3_AppendHandshakeNumber(ss, tls13_GroupForECDHEKeyShare(pair), 2);
|
| + if (rv != SECSuccess)
|
| + return rv;
|
| +
|
| + rv = ssl3_AppendHandshakeNumber(ss, tls13_SizeOfECDHEKeyShareKEX(pair), 2);
|
| + if (rv != SECSuccess)
|
| + return rv;
|
| +
|
| + rv = tls13_EncodeECDHEKeyShareKEX(ss, pair);
|
| + if (rv != SECSuccess)
|
| + return rv;
|
| +
|
| + return SECSuccess;
|
| +}
|
| +
|
| +static PRInt32
|
| +tls13_ClientSendKeyShareXtn(sslSocket *ss, PRBool append,
|
| + PRUint32 maxBytes)
|
| +{
|
| + SECStatus rv;
|
| + PRUint32 entry_length;
|
| + PRUint32 extension_length;
|
| +
|
| + if (ss->version < SSL_LIBRARY_VERSION_TLS_1_3) {
|
| + return 0;
|
| + }
|
| +
|
| + /* Optimistically try to send an ECDHE key using the
|
| + * preexisting key (in future will be keys) */
|
| + SSL_TRC(3, ("%d: TLS13[%d]: send client key share xtn",
|
| + SSL_GETPID(), ss->fd));
|
| +
|
| + entry_length = tls13_SizeOfKeyShareEntry(ss->ephemeralECDHKeyPair);
|
| + /* Type + length + vector_length + entry */
|
| + extension_length = 2 + 2 + 2 + entry_length;
|
| +
|
| + if (maxBytes < extension_length) {
|
| + PORT_Assert(0);
|
| + return 0;
|
| + }
|
| +
|
| + if (append) {
|
| + rv = ssl3_AppendHandshakeNumber(ss, ssl_tls13_key_share_xtn, 2);
|
| + if (rv != SECSuccess)
|
| + goto loser;
|
| + rv = ssl3_AppendHandshakeNumber(ss, entry_length + 2, 2); /* Extension length */
|
| + if (rv != SECSuccess)
|
| + goto loser;
|
| + rv = ssl3_AppendHandshakeNumber(ss, entry_length, 2); /* Vector length */
|
| + if (rv != SECSuccess)
|
| + goto loser;
|
| + rv = tls13_EncodeKeyShareEntry(ss, ss->ephemeralECDHKeyPair);
|
| + if (rv != SECSuccess)
|
| + goto loser;
|
| +
|
| + ss->xtnData.advertised[ss->xtnData.numAdvertised++] =
|
| + ssl_tls13_key_share_xtn;
|
| + }
|
| +
|
| + return extension_length;
|
| +
|
| +loser:
|
| + return -1;
|
| +}
|
| +
|
| +static SECStatus
|
| +tls13_HandleKeyShareEntry(sslSocket *ss, SECItem *data)
|
| +{
|
| + SECStatus rv;
|
| + PRInt32 group;
|
| + TLS13KeyShareEntry *ks = NULL;
|
| + SECItem share = { siBuffer, NULL, 0 };
|
| +
|
| + group = ssl3_ConsumeHandshakeNumber(ss, 2, &data->data, &data->len);
|
| + if (group < 0) {
|
| + PORT_SetError(SSL_ERROR_RX_MALFORMED_KEY_SHARE);
|
| + goto loser;
|
| + }
|
| +
|
| + rv = ssl3_ConsumeHandshakeVariable(ss, &share, 2, &data->data,
|
| + &data->len);
|
| + if (rv != SECSuccess)
|
| + goto loser;
|
| +
|
| + ks = PORT_ZNew(TLS13KeyShareEntry);
|
| + if (!ks)
|
| + goto loser;
|
| + ks->group = group;
|
| +
|
| + rv = SECITEM_CopyItem(NULL, &ks->key_exchange, &share);
|
| + if (rv != SECSuccess)
|
| + goto loser;
|
| +
|
| + PR_APPEND_LINK(&ks->link, &ss->ssl3.hs.remoteKeyShares);
|
| + return SECSuccess;
|
| +
|
| +loser:
|
| + if (ks)
|
| + 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
|
| + * share is processed in tls13_HandleServerKeyShare(). */
|
| +static SECStatus
|
| +tls13_ClientHandleKeyShareXtn(sslSocket *ss, PRUint16 ex_type, SECItem *data)
|
| +{
|
| + SECStatus rv;
|
| +
|
| + PORT_Assert(!ss->sec.isServer);
|
| + if (ss->version < SSL_LIBRARY_VERSION_TLS_1_3) {
|
| + /* This can't happen because the extension processing
|
| + * code filters out TLS 1.3 extensions when not in
|
| + * TLS 1.3 mode. */
|
| + PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
|
| + return SECFailure;
|
| + }
|
| +
|
| + SSL_TRC(3, ("%d: SSL3[%d]: handle key_share extension",
|
| + SSL_GETPID(), ss->fd));
|
| +
|
| + rv = tls13_HandleKeyShareEntry(ss, data);
|
| + if (rv != SECSuccess) {
|
| + PORT_SetError(SSL_ERROR_RX_MALFORMED_KEY_SHARE);
|
| + return SECFailure;
|
| + }
|
| +
|
| + if (data->len) {
|
| + PORT_SetError(SSL_ERROR_RX_MALFORMED_KEY_SHARE);
|
| + return SECFailure;
|
| + }
|
| +
|
| + return SECSuccess;
|
| +}
|
| +
|
| +/* Handle an incoming KeyShare extension at the server and copy to
|
| + * |ss->ssl3.hs.remoteKeyShares| for future use. The key
|
| + * share is processed in tls13_HandleClientKeyShare(). */
|
| +static SECStatus
|
| +tls13_ServerHandleKeyShareXtn(sslSocket *ss, PRUint16 ex_type, SECItem *data)
|
| +{
|
| + SECStatus rv;
|
| + PRInt32 length;
|
| +
|
| + PORT_Assert(ss->sec.isServer);
|
| + if (ss->version < SSL_LIBRARY_VERSION_TLS_1_3) {
|
| + return SECSuccess;
|
| + }
|
| +
|
| + SSL_TRC(3, ("%d: SSL3[%d]: handle key_share extension",
|
| + SSL_GETPID(), ss->fd));
|
| +
|
| + /* Redundant length because of TLS encoding (this vector consumes
|
| + * the entire extension.) */
|
| + length = ssl3_ConsumeHandshakeNumber(ss, 2, &data->data,
|
| + &data->len);
|
| + if (length < 0)
|
| + goto loser;
|
| + if (length != data->len) {
|
| + /* Check for consistency */
|
| + PORT_SetError(SSL_ERROR_RX_MALFORMED_KEY_SHARE);
|
| + goto loser;
|
| + }
|
| +
|
| + while (data->len) {
|
| + rv = tls13_HandleKeyShareEntry(ss, data);
|
| + if (rv != SECSuccess)
|
| + goto loser;
|
| + }
|
| + return SECSuccess;
|
| +
|
| +loser:
|
| + tls13_DestroyKeyShares(&ss->ssl3.hs.remoteKeyShares);
|
| + return SECFailure;
|
| +}
|
| +
|
| +PRInt32
|
| +tls13_ServerSendKeyShareXtn(sslSocket *ss, PRBool append,
|
| + PRUint32 maxBytes)
|
| +{
|
| + PRUint32 extension_length;
|
| + PRUint32 entry_length;
|
| + SECStatus rv;
|
| +
|
| + switch (ss->ssl3.hs.kea_def->exchKeyType) {
|
| +#ifndef NSS_DISABLE_ECC
|
| + case ssl_kea_ecdh:
|
| + PORT_Assert(ss->ephemeralECDHKeyPair);
|
| + break;
|
| +#endif
|
| + default:
|
| + /* got an unknown or unsupported Key Exchange Algorithm.
|
| + * Can't happen because tls13_HandleClientKeyShare
|
| + * enforces that we are ssl_kea_ecdh. */
|
| + PORT_Assert(0);
|
| + tls13_FatalError(ss, SEC_ERROR_UNSUPPORTED_KEYALG, internal_error);
|
| + return SECFailure;
|
| + }
|
| +
|
| + entry_length = tls13_SizeOfKeyShareEntry(ss->ephemeralECDHKeyPair);
|
| + extension_length = 2 + 2 + entry_length; /* Type + length + entry_length */
|
| + if (maxBytes < extension_length) {
|
| + PORT_Assert(0);
|
| + return 0;
|
| + }
|
| +
|
| + if (append) {
|
| + rv = ssl3_AppendHandshakeNumber(ss, ssl_tls13_key_share_xtn, 2);
|
| + if (rv != SECSuccess)
|
| + goto loser;
|
| +
|
| + rv = ssl3_AppendHandshakeNumber(ss, entry_length, 2);
|
| + if (rv != SECSuccess)
|
| + goto loser;
|
| +
|
| + rv = tls13_EncodeKeyShareEntry(ss, ss->ephemeralECDHKeyPair);
|
| + if (rv != SECSuccess)
|
| + goto loser;
|
| + }
|
| +
|
| + return extension_length;
|
| +
|
| +loser:
|
| + return -1;
|
| +}
|
|
|