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; |
+} |