security/nss/lib/ssl/ssl3ext.c

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

michael@0 1 /*
michael@0 2 * SSL3 Protocol
michael@0 3 *
michael@0 4 * This Source Code Form is subject to the terms of the Mozilla Public
michael@0 5 * License, v. 2.0. If a copy of the MPL was not distributed with this
michael@0 6 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
michael@0 7
michael@0 8 /* TLS extension code moved here from ssl3ecc.c */
michael@0 9
michael@0 10 #include "nssrenam.h"
michael@0 11 #include "nss.h"
michael@0 12 #include "ssl.h"
michael@0 13 #include "sslproto.h"
michael@0 14 #include "sslimpl.h"
michael@0 15 #include "pk11pub.h"
michael@0 16 #ifdef NO_PKCS11_BYPASS
michael@0 17 #include "blapit.h"
michael@0 18 #else
michael@0 19 #include "blapi.h"
michael@0 20 #endif
michael@0 21 #include "prinit.h"
michael@0 22
michael@0 23 static unsigned char key_name[SESS_TICKET_KEY_NAME_LEN];
michael@0 24 static PK11SymKey *session_ticket_enc_key_pkcs11 = NULL;
michael@0 25 static PK11SymKey *session_ticket_mac_key_pkcs11 = NULL;
michael@0 26
michael@0 27 #ifndef NO_PKCS11_BYPASS
michael@0 28 static unsigned char session_ticket_enc_key[AES_256_KEY_LENGTH];
michael@0 29 static unsigned char session_ticket_mac_key[SHA256_LENGTH];
michael@0 30
michael@0 31 static PRBool session_ticket_keys_initialized = PR_FALSE;
michael@0 32 #endif
michael@0 33 static PRCallOnceType generate_session_keys_once;
michael@0 34
michael@0 35 /* forward static function declarations */
michael@0 36 static SECStatus ssl3_ParseEncryptedSessionTicket(sslSocket *ss,
michael@0 37 SECItem *data, EncryptedSessionTicket *enc_session_ticket);
michael@0 38 static SECStatus ssl3_AppendToItem(SECItem *item, const unsigned char *buf,
michael@0 39 PRUint32 bytes);
michael@0 40 static SECStatus ssl3_AppendNumberToItem(SECItem *item, PRUint32 num,
michael@0 41 PRInt32 lenSize);
michael@0 42 static SECStatus ssl3_GetSessionTicketKeysPKCS11(sslSocket *ss,
michael@0 43 PK11SymKey **aes_key, PK11SymKey **mac_key);
michael@0 44 #ifndef NO_PKCS11_BYPASS
michael@0 45 static SECStatus ssl3_GetSessionTicketKeys(const unsigned char **aes_key,
michael@0 46 PRUint32 *aes_key_length, const unsigned char **mac_key,
michael@0 47 PRUint32 *mac_key_length);
michael@0 48 #endif
michael@0 49 static PRInt32 ssl3_SendRenegotiationInfoXtn(sslSocket * ss,
michael@0 50 PRBool append, PRUint32 maxBytes);
michael@0 51 static SECStatus ssl3_HandleRenegotiationInfoXtn(sslSocket *ss,
michael@0 52 PRUint16 ex_type, SECItem *data);
michael@0 53 static SECStatus ssl3_ClientHandleNextProtoNegoXtn(sslSocket *ss,
michael@0 54 PRUint16 ex_type, SECItem *data);
michael@0 55 static SECStatus ssl3_ClientHandleAppProtoXtn(sslSocket *ss,
michael@0 56 PRUint16 ex_type, SECItem *data);
michael@0 57 static SECStatus ssl3_ServerHandleNextProtoNegoXtn(sslSocket *ss,
michael@0 58 PRUint16 ex_type, SECItem *data);
michael@0 59 static SECStatus ssl3_ServerHandleAppProtoXtn(sslSocket *ss, PRUint16 ex_type,
michael@0 60 SECItem *data);
michael@0 61 static PRInt32 ssl3_ClientSendNextProtoNegoXtn(sslSocket *ss, PRBool append,
michael@0 62 PRUint32 maxBytes);
michael@0 63 static PRInt32 ssl3_ClientSendAppProtoXtn(sslSocket *ss, PRBool append,
michael@0 64 PRUint32 maxBytes);
michael@0 65 static PRInt32 ssl3_ServerSendAppProtoXtn(sslSocket *ss, PRBool append,
michael@0 66 PRUint32 maxBytes);
michael@0 67 static PRInt32 ssl3_SendUseSRTPXtn(sslSocket *ss, PRBool append,
michael@0 68 PRUint32 maxBytes);
michael@0 69 static SECStatus ssl3_HandleUseSRTPXtn(sslSocket * ss, PRUint16 ex_type,
michael@0 70 SECItem *data);
michael@0 71 static PRInt32 ssl3_ServerSendStatusRequestXtn(sslSocket * ss,
michael@0 72 PRBool append, PRUint32 maxBytes);
michael@0 73 static SECStatus ssl3_ServerHandleStatusRequestXtn(sslSocket *ss,
michael@0 74 PRUint16 ex_type, SECItem *data);
michael@0 75 static SECStatus ssl3_ClientHandleStatusRequestXtn(sslSocket *ss,
michael@0 76 PRUint16 ex_type,
michael@0 77 SECItem *data);
michael@0 78 static PRInt32 ssl3_ClientSendStatusRequestXtn(sslSocket * ss, PRBool append,
michael@0 79 PRUint32 maxBytes);
michael@0 80 static PRInt32 ssl3_ClientSendSigAlgsXtn(sslSocket *ss, PRBool append,
michael@0 81 PRUint32 maxBytes);
michael@0 82 static SECStatus ssl3_ServerHandleSigAlgsXtn(sslSocket *ss, PRUint16 ex_type,
michael@0 83 SECItem *data);
michael@0 84
michael@0 85 /*
michael@0 86 * Write bytes. Using this function means the SECItem structure
michael@0 87 * cannot be freed. The caller is expected to call this function
michael@0 88 * on a shallow copy of the structure.
michael@0 89 */
michael@0 90 static SECStatus
michael@0 91 ssl3_AppendToItem(SECItem *item, const unsigned char *buf, PRUint32 bytes)
michael@0 92 {
michael@0 93 if (bytes > item->len)
michael@0 94 return SECFailure;
michael@0 95
michael@0 96 PORT_Memcpy(item->data, buf, bytes);
michael@0 97 item->data += bytes;
michael@0 98 item->len -= bytes;
michael@0 99 return SECSuccess;
michael@0 100 }
michael@0 101
michael@0 102 /*
michael@0 103 * Write a number in network byte order. Using this function means the
michael@0 104 * SECItem structure cannot be freed. The caller is expected to call
michael@0 105 * this function on a shallow copy of the structure.
michael@0 106 */
michael@0 107 static SECStatus
michael@0 108 ssl3_AppendNumberToItem(SECItem *item, PRUint32 num, PRInt32 lenSize)
michael@0 109 {
michael@0 110 SECStatus rv;
michael@0 111 PRUint8 b[4];
michael@0 112 PRUint8 * p = b;
michael@0 113
michael@0 114 switch (lenSize) {
michael@0 115 case 4:
michael@0 116 *p++ = (PRUint8) (num >> 24);
michael@0 117 case 3:
michael@0 118 *p++ = (PRUint8) (num >> 16);
michael@0 119 case 2:
michael@0 120 *p++ = (PRUint8) (num >> 8);
michael@0 121 case 1:
michael@0 122 *p = (PRUint8) num;
michael@0 123 }
michael@0 124 rv = ssl3_AppendToItem(item, &b[0], lenSize);
michael@0 125 return rv;
michael@0 126 }
michael@0 127
michael@0 128 static SECStatus ssl3_SessionTicketShutdown(void* appData, void* nssData)
michael@0 129 {
michael@0 130 if (session_ticket_enc_key_pkcs11) {
michael@0 131 PK11_FreeSymKey(session_ticket_enc_key_pkcs11);
michael@0 132 session_ticket_enc_key_pkcs11 = NULL;
michael@0 133 }
michael@0 134 if (session_ticket_mac_key_pkcs11) {
michael@0 135 PK11_FreeSymKey(session_ticket_mac_key_pkcs11);
michael@0 136 session_ticket_mac_key_pkcs11 = NULL;
michael@0 137 }
michael@0 138 PORT_Memset(&generate_session_keys_once, 0,
michael@0 139 sizeof(generate_session_keys_once));
michael@0 140 return SECSuccess;
michael@0 141 }
michael@0 142
michael@0 143
michael@0 144 static PRStatus
michael@0 145 ssl3_GenerateSessionTicketKeysPKCS11(void *data)
michael@0 146 {
michael@0 147 SECStatus rv;
michael@0 148 sslSocket *ss = (sslSocket *)data;
michael@0 149 SECKEYPrivateKey *svrPrivKey = ss->serverCerts[kt_rsa].SERVERKEY;
michael@0 150 SECKEYPublicKey *svrPubKey = ss->serverCerts[kt_rsa].serverKeyPair->pubKey;
michael@0 151
michael@0 152 if (svrPrivKey == NULL || svrPubKey == NULL) {
michael@0 153 SSL_DBG(("%d: SSL[%d]: Pub or priv key(s) is NULL.",
michael@0 154 SSL_GETPID(), ss->fd));
michael@0 155 goto loser;
michael@0 156 }
michael@0 157
michael@0 158 /* Get a copy of the session keys from shared memory. */
michael@0 159 PORT_Memcpy(key_name, SESS_TICKET_KEY_NAME_PREFIX,
michael@0 160 sizeof(SESS_TICKET_KEY_NAME_PREFIX));
michael@0 161 if (!ssl_GetSessionTicketKeysPKCS11(svrPrivKey, svrPubKey,
michael@0 162 ss->pkcs11PinArg, &key_name[SESS_TICKET_KEY_NAME_PREFIX_LEN],
michael@0 163 &session_ticket_enc_key_pkcs11, &session_ticket_mac_key_pkcs11))
michael@0 164 return PR_FAILURE;
michael@0 165
michael@0 166 rv = NSS_RegisterShutdown(ssl3_SessionTicketShutdown, NULL);
michael@0 167 if (rv != SECSuccess)
michael@0 168 goto loser;
michael@0 169
michael@0 170 return PR_SUCCESS;
michael@0 171
michael@0 172 loser:
michael@0 173 ssl3_SessionTicketShutdown(NULL, NULL);
michael@0 174 return PR_FAILURE;
michael@0 175 }
michael@0 176
michael@0 177 static SECStatus
michael@0 178 ssl3_GetSessionTicketKeysPKCS11(sslSocket *ss, PK11SymKey **aes_key,
michael@0 179 PK11SymKey **mac_key)
michael@0 180 {
michael@0 181 if (PR_CallOnceWithArg(&generate_session_keys_once,
michael@0 182 ssl3_GenerateSessionTicketKeysPKCS11, ss) != PR_SUCCESS)
michael@0 183 return SECFailure;
michael@0 184
michael@0 185 if (session_ticket_enc_key_pkcs11 == NULL ||
michael@0 186 session_ticket_mac_key_pkcs11 == NULL)
michael@0 187 return SECFailure;
michael@0 188
michael@0 189 *aes_key = session_ticket_enc_key_pkcs11;
michael@0 190 *mac_key = session_ticket_mac_key_pkcs11;
michael@0 191 return SECSuccess;
michael@0 192 }
michael@0 193
michael@0 194 #ifndef NO_PKCS11_BYPASS
michael@0 195 static PRStatus
michael@0 196 ssl3_GenerateSessionTicketKeys(void)
michael@0 197 {
michael@0 198 PORT_Memcpy(key_name, SESS_TICKET_KEY_NAME_PREFIX,
michael@0 199 sizeof(SESS_TICKET_KEY_NAME_PREFIX));
michael@0 200
michael@0 201 if (!ssl_GetSessionTicketKeys(&key_name[SESS_TICKET_KEY_NAME_PREFIX_LEN],
michael@0 202 session_ticket_enc_key, session_ticket_mac_key))
michael@0 203 return PR_FAILURE;
michael@0 204
michael@0 205 session_ticket_keys_initialized = PR_TRUE;
michael@0 206 return PR_SUCCESS;
michael@0 207 }
michael@0 208
michael@0 209 static SECStatus
michael@0 210 ssl3_GetSessionTicketKeys(const unsigned char **aes_key,
michael@0 211 PRUint32 *aes_key_length, const unsigned char **mac_key,
michael@0 212 PRUint32 *mac_key_length)
michael@0 213 {
michael@0 214 if (PR_CallOnce(&generate_session_keys_once,
michael@0 215 ssl3_GenerateSessionTicketKeys) != PR_SUCCESS)
michael@0 216 return SECFailure;
michael@0 217
michael@0 218 if (!session_ticket_keys_initialized)
michael@0 219 return SECFailure;
michael@0 220
michael@0 221 *aes_key = session_ticket_enc_key;
michael@0 222 *aes_key_length = sizeof(session_ticket_enc_key);
michael@0 223 *mac_key = session_ticket_mac_key;
michael@0 224 *mac_key_length = sizeof(session_ticket_mac_key);
michael@0 225
michael@0 226 return SECSuccess;
michael@0 227 }
michael@0 228 #endif
michael@0 229
michael@0 230 /* Table of handlers for received TLS hello extensions, one per extension.
michael@0 231 * In the second generation, this table will be dynamic, and functions
michael@0 232 * will be registered here.
michael@0 233 */
michael@0 234 /* This table is used by the server, to handle client hello extensions. */
michael@0 235 static const ssl3HelloExtensionHandler clientHelloHandlers[] = {
michael@0 236 { ssl_server_name_xtn, &ssl3_HandleServerNameXtn },
michael@0 237 #ifndef NSS_DISABLE_ECC
michael@0 238 { ssl_elliptic_curves_xtn, &ssl3_HandleSupportedCurvesXtn },
michael@0 239 { ssl_ec_point_formats_xtn, &ssl3_HandleSupportedPointFormatsXtn },
michael@0 240 #endif
michael@0 241 { ssl_session_ticket_xtn, &ssl3_ServerHandleSessionTicketXtn },
michael@0 242 { ssl_renegotiation_info_xtn, &ssl3_HandleRenegotiationInfoXtn },
michael@0 243 { ssl_next_proto_nego_xtn, &ssl3_ServerHandleNextProtoNegoXtn },
michael@0 244 { ssl_app_layer_protocol_xtn, &ssl3_ServerHandleAppProtoXtn },
michael@0 245 { ssl_use_srtp_xtn, &ssl3_HandleUseSRTPXtn },
michael@0 246 { ssl_cert_status_xtn, &ssl3_ServerHandleStatusRequestXtn },
michael@0 247 { ssl_signature_algorithms_xtn, &ssl3_ServerHandleSigAlgsXtn },
michael@0 248 { -1, NULL }
michael@0 249 };
michael@0 250
michael@0 251 /* These two tables are used by the client, to handle server hello
michael@0 252 * extensions. */
michael@0 253 static const ssl3HelloExtensionHandler serverHelloHandlersTLS[] = {
michael@0 254 { ssl_server_name_xtn, &ssl3_HandleServerNameXtn },
michael@0 255 /* TODO: add a handler for ssl_ec_point_formats_xtn */
michael@0 256 { ssl_session_ticket_xtn, &ssl3_ClientHandleSessionTicketXtn },
michael@0 257 { ssl_renegotiation_info_xtn, &ssl3_HandleRenegotiationInfoXtn },
michael@0 258 { ssl_next_proto_nego_xtn, &ssl3_ClientHandleNextProtoNegoXtn },
michael@0 259 { ssl_app_layer_protocol_xtn, &ssl3_ClientHandleAppProtoXtn },
michael@0 260 { ssl_use_srtp_xtn, &ssl3_HandleUseSRTPXtn },
michael@0 261 { ssl_cert_status_xtn, &ssl3_ClientHandleStatusRequestXtn },
michael@0 262 { -1, NULL }
michael@0 263 };
michael@0 264
michael@0 265 static const ssl3HelloExtensionHandler serverHelloHandlersSSL3[] = {
michael@0 266 { ssl_renegotiation_info_xtn, &ssl3_HandleRenegotiationInfoXtn },
michael@0 267 { -1, NULL }
michael@0 268 };
michael@0 269
michael@0 270 /* Tables of functions to format TLS hello extensions, one function per
michael@0 271 * extension.
michael@0 272 * These static tables are for the formatting of client hello extensions.
michael@0 273 * The server's table of hello senders is dynamic, in the socket struct,
michael@0 274 * and sender functions are registered there.
michael@0 275 */
michael@0 276 static const
michael@0 277 ssl3HelloExtensionSender clientHelloSendersTLS[SSL_MAX_EXTENSIONS] = {
michael@0 278 { ssl_server_name_xtn, &ssl3_SendServerNameXtn },
michael@0 279 { ssl_renegotiation_info_xtn, &ssl3_SendRenegotiationInfoXtn },
michael@0 280 #ifndef NSS_DISABLE_ECC
michael@0 281 { ssl_elliptic_curves_xtn, &ssl3_SendSupportedCurvesXtn },
michael@0 282 { ssl_ec_point_formats_xtn, &ssl3_SendSupportedPointFormatsXtn },
michael@0 283 #endif
michael@0 284 { ssl_session_ticket_xtn, &ssl3_SendSessionTicketXtn },
michael@0 285 { ssl_next_proto_nego_xtn, &ssl3_ClientSendNextProtoNegoXtn },
michael@0 286 { ssl_app_layer_protocol_xtn, &ssl3_ClientSendAppProtoXtn },
michael@0 287 { ssl_use_srtp_xtn, &ssl3_SendUseSRTPXtn },
michael@0 288 { ssl_cert_status_xtn, &ssl3_ClientSendStatusRequestXtn },
michael@0 289 { ssl_signature_algorithms_xtn, &ssl3_ClientSendSigAlgsXtn }
michael@0 290 /* any extra entries will appear as { 0, NULL } */
michael@0 291 };
michael@0 292
michael@0 293 static const
michael@0 294 ssl3HelloExtensionSender clientHelloSendersSSL3[SSL_MAX_EXTENSIONS] = {
michael@0 295 { ssl_renegotiation_info_xtn, &ssl3_SendRenegotiationInfoXtn }
michael@0 296 /* any extra entries will appear as { 0, NULL } */
michael@0 297 };
michael@0 298
michael@0 299 static PRBool
michael@0 300 arrayContainsExtension(const PRUint16 *array, PRUint32 len, PRUint16 ex_type)
michael@0 301 {
michael@0 302 int i;
michael@0 303 for (i = 0; i < len; i++) {
michael@0 304 if (ex_type == array[i])
michael@0 305 return PR_TRUE;
michael@0 306 }
michael@0 307 return PR_FALSE;
michael@0 308 }
michael@0 309
michael@0 310 PRBool
michael@0 311 ssl3_ExtensionNegotiated(sslSocket *ss, PRUint16 ex_type) {
michael@0 312 TLSExtensionData *xtnData = &ss->xtnData;
michael@0 313 return arrayContainsExtension(xtnData->negotiated,
michael@0 314 xtnData->numNegotiated, ex_type);
michael@0 315 }
michael@0 316
michael@0 317 static PRBool
michael@0 318 ssl3_ClientExtensionAdvertised(sslSocket *ss, PRUint16 ex_type) {
michael@0 319 TLSExtensionData *xtnData = &ss->xtnData;
michael@0 320 return arrayContainsExtension(xtnData->advertised,
michael@0 321 xtnData->numAdvertised, ex_type);
michael@0 322 }
michael@0 323
michael@0 324 /* Format an SNI extension, using the name from the socket's URL,
michael@0 325 * unless that name is a dotted decimal string.
michael@0 326 * Used by client and server.
michael@0 327 */
michael@0 328 PRInt32
michael@0 329 ssl3_SendServerNameXtn(sslSocket * ss, PRBool append,
michael@0 330 PRUint32 maxBytes)
michael@0 331 {
michael@0 332 SECStatus rv;
michael@0 333 if (!ss)
michael@0 334 return 0;
michael@0 335 if (!ss->sec.isServer) {
michael@0 336 PRUint32 len;
michael@0 337 PRNetAddr netAddr;
michael@0 338
michael@0 339 /* must have a hostname */
michael@0 340 if (!ss->url || !ss->url[0])
michael@0 341 return 0;
michael@0 342 /* must not be an IPv4 or IPv6 address */
michael@0 343 if (PR_SUCCESS == PR_StringToNetAddr(ss->url, &netAddr)) {
michael@0 344 /* is an IP address (v4 or v6) */
michael@0 345 return 0;
michael@0 346 }
michael@0 347 len = PORT_Strlen(ss->url);
michael@0 348 if (append && maxBytes >= len + 9) {
michael@0 349 /* extension_type */
michael@0 350 rv = ssl3_AppendHandshakeNumber(ss, ssl_server_name_xtn, 2);
michael@0 351 if (rv != SECSuccess) return -1;
michael@0 352 /* length of extension_data */
michael@0 353 rv = ssl3_AppendHandshakeNumber(ss, len + 5, 2);
michael@0 354 if (rv != SECSuccess) return -1;
michael@0 355 /* length of server_name_list */
michael@0 356 rv = ssl3_AppendHandshakeNumber(ss, len + 3, 2);
michael@0 357 if (rv != SECSuccess) return -1;
michael@0 358 /* Name Type (sni_host_name) */
michael@0 359 rv = ssl3_AppendHandshake(ss, "\0", 1);
michael@0 360 if (rv != SECSuccess) return -1;
michael@0 361 /* HostName (length and value) */
michael@0 362 rv = ssl3_AppendHandshakeVariable(ss, (PRUint8 *)ss->url, len, 2);
michael@0 363 if (rv != SECSuccess) return -1;
michael@0 364 if (!ss->sec.isServer) {
michael@0 365 TLSExtensionData *xtnData = &ss->xtnData;
michael@0 366 xtnData->advertised[xtnData->numAdvertised++] =
michael@0 367 ssl_server_name_xtn;
michael@0 368 }
michael@0 369 }
michael@0 370 return len + 9;
michael@0 371 }
michael@0 372 /* Server side */
michael@0 373 if (append && maxBytes >= 4) {
michael@0 374 rv = ssl3_AppendHandshakeNumber(ss, ssl_server_name_xtn, 2);
michael@0 375 if (rv != SECSuccess) return -1;
michael@0 376 /* length of extension_data */
michael@0 377 rv = ssl3_AppendHandshakeNumber(ss, 0, 2);
michael@0 378 if (rv != SECSuccess) return -1;
michael@0 379 }
michael@0 380 return 4;
michael@0 381 }
michael@0 382
michael@0 383 /* handle an incoming SNI extension, by ignoring it. */
michael@0 384 SECStatus
michael@0 385 ssl3_HandleServerNameXtn(sslSocket * ss, PRUint16 ex_type, SECItem *data)
michael@0 386 {
michael@0 387 SECItem *names = NULL;
michael@0 388 PRUint32 listCount = 0, namesPos = 0, i;
michael@0 389 TLSExtensionData *xtnData = &ss->xtnData;
michael@0 390 SECItem ldata;
michael@0 391 PRInt32 listLenBytes = 0;
michael@0 392
michael@0 393 if (!ss->sec.isServer) {
michael@0 394 /* Verify extension_data is empty. */
michael@0 395 if (data->data || data->len ||
michael@0 396 !ssl3_ExtensionNegotiated(ss, ssl_server_name_xtn)) {
michael@0 397 /* malformed or was not initiated by the client.*/
michael@0 398 return SECFailure;
michael@0 399 }
michael@0 400 return SECSuccess;
michael@0 401 }
michael@0 402
michael@0 403 /* Server side - consume client data and register server sender. */
michael@0 404 /* do not parse the data if don't have user extension handling function. */
michael@0 405 if (!ss->sniSocketConfig) {
michael@0 406 return SECSuccess;
michael@0 407 }
michael@0 408 /* length of server_name_list */
michael@0 409 listLenBytes = ssl3_ConsumeHandshakeNumber(ss, 2, &data->data, &data->len);
michael@0 410 if (listLenBytes == 0 || listLenBytes != data->len) {
michael@0 411 return SECFailure;
michael@0 412 }
michael@0 413 ldata = *data;
michael@0 414 /* Calculate the size of the array.*/
michael@0 415 while (listLenBytes > 0) {
michael@0 416 SECItem litem;
michael@0 417 SECStatus rv;
michael@0 418 PRInt32 type;
michael@0 419 /* Name Type (sni_host_name) */
michael@0 420 type = ssl3_ConsumeHandshakeNumber(ss, 1, &ldata.data, &ldata.len);
michael@0 421 if (!ldata.len) {
michael@0 422 return SECFailure;
michael@0 423 }
michael@0 424 rv = ssl3_ConsumeHandshakeVariable(ss, &litem, 2, &ldata.data, &ldata.len);
michael@0 425 if (rv != SECSuccess) {
michael@0 426 return SECFailure;
michael@0 427 }
michael@0 428 /* Adjust total length for cunsumed item, item len and type.*/
michael@0 429 listLenBytes -= litem.len + 3;
michael@0 430 if (listLenBytes > 0 && !ldata.len) {
michael@0 431 return SECFailure;
michael@0 432 }
michael@0 433 listCount += 1;
michael@0 434 }
michael@0 435 if (!listCount) {
michael@0 436 return SECFailure;
michael@0 437 }
michael@0 438 names = PORT_ZNewArray(SECItem, listCount);
michael@0 439 if (!names) {
michael@0 440 return SECFailure;
michael@0 441 }
michael@0 442 for (i = 0;i < listCount;i++) {
michael@0 443 int j;
michael@0 444 PRInt32 type;
michael@0 445 SECStatus rv;
michael@0 446 PRBool nametypePresent = PR_FALSE;
michael@0 447 /* Name Type (sni_host_name) */
michael@0 448 type = ssl3_ConsumeHandshakeNumber(ss, 1, &data->data, &data->len);
michael@0 449 /* Check if we have such type in the list */
michael@0 450 for (j = 0;j < listCount && names[j].data;j++) {
michael@0 451 if (names[j].type == type) {
michael@0 452 nametypePresent = PR_TRUE;
michael@0 453 break;
michael@0 454 }
michael@0 455 }
michael@0 456 /* HostName (length and value) */
michael@0 457 rv = ssl3_ConsumeHandshakeVariable(ss, &names[namesPos], 2,
michael@0 458 &data->data, &data->len);
michael@0 459 if (rv != SECSuccess) {
michael@0 460 goto loser;
michael@0 461 }
michael@0 462 if (nametypePresent == PR_FALSE) {
michael@0 463 namesPos += 1;
michael@0 464 }
michael@0 465 }
michael@0 466 /* Free old and set the new data. */
michael@0 467 if (xtnData->sniNameArr) {
michael@0 468 PORT_Free(ss->xtnData.sniNameArr);
michael@0 469 }
michael@0 470 xtnData->sniNameArr = names;
michael@0 471 xtnData->sniNameArrSize = namesPos;
michael@0 472 xtnData->negotiated[xtnData->numNegotiated++] = ssl_server_name_xtn;
michael@0 473
michael@0 474 return SECSuccess;
michael@0 475
michael@0 476 loser:
michael@0 477 PORT_Free(names);
michael@0 478 return SECFailure;
michael@0 479 }
michael@0 480
michael@0 481 /* Called by both clients and servers.
michael@0 482 * Clients sends a filled in session ticket if one is available, and otherwise
michael@0 483 * sends an empty ticket. Servers always send empty tickets.
michael@0 484 */
michael@0 485 PRInt32
michael@0 486 ssl3_SendSessionTicketXtn(
michael@0 487 sslSocket * ss,
michael@0 488 PRBool append,
michael@0 489 PRUint32 maxBytes)
michael@0 490 {
michael@0 491 PRInt32 extension_length;
michael@0 492 NewSessionTicket *session_ticket = NULL;
michael@0 493 sslSessionID *sid = ss->sec.ci.sid;
michael@0 494
michael@0 495 /* Ignore the SessionTicket extension if processing is disabled. */
michael@0 496 if (!ss->opt.enableSessionTickets)
michael@0 497 return 0;
michael@0 498
michael@0 499 /* Empty extension length = extension_type (2-bytes) +
michael@0 500 * length(extension_data) (2-bytes)
michael@0 501 */
michael@0 502 extension_length = 4;
michael@0 503
michael@0 504 /* If we are a client then send a session ticket if one is availble.
michael@0 505 * Servers that support the extension and are willing to negotiate the
michael@0 506 * the extension always respond with an empty extension.
michael@0 507 */
michael@0 508 if (!ss->sec.isServer) {
michael@0 509 /* The caller must be holding sid->u.ssl3.lock for reading. We cannot
michael@0 510 * just acquire and release the lock within this function because the
michael@0 511 * caller will call this function twice, and we need the inputs to be
michael@0 512 * consistent between the two calls. Note that currently the caller
michael@0 513 * will only be holding the lock when we are the client and when we're
michael@0 514 * attempting to resume an existing session.
michael@0 515 */
michael@0 516
michael@0 517 session_ticket = &sid->u.ssl3.locked.sessionTicket;
michael@0 518 if (session_ticket->ticket.data) {
michael@0 519 if (ss->xtnData.ticketTimestampVerified) {
michael@0 520 extension_length += session_ticket->ticket.len;
michael@0 521 } else if (!append &&
michael@0 522 (session_ticket->ticket_lifetime_hint == 0 ||
michael@0 523 (session_ticket->ticket_lifetime_hint +
michael@0 524 session_ticket->received_timestamp > ssl_Time()))) {
michael@0 525 extension_length += session_ticket->ticket.len;
michael@0 526 ss->xtnData.ticketTimestampVerified = PR_TRUE;
michael@0 527 }
michael@0 528 }
michael@0 529 }
michael@0 530
michael@0 531 if (append && maxBytes >= extension_length) {
michael@0 532 SECStatus rv;
michael@0 533 /* extension_type */
michael@0 534 rv = ssl3_AppendHandshakeNumber(ss, ssl_session_ticket_xtn, 2);
michael@0 535 if (rv != SECSuccess)
michael@0 536 goto loser;
michael@0 537 if (session_ticket && session_ticket->ticket.data &&
michael@0 538 ss->xtnData.ticketTimestampVerified) {
michael@0 539 rv = ssl3_AppendHandshakeVariable(ss, session_ticket->ticket.data,
michael@0 540 session_ticket->ticket.len, 2);
michael@0 541 ss->xtnData.ticketTimestampVerified = PR_FALSE;
michael@0 542 ss->xtnData.sentSessionTicketInClientHello = PR_TRUE;
michael@0 543 } else {
michael@0 544 rv = ssl3_AppendHandshakeNumber(ss, 0, 2);
michael@0 545 }
michael@0 546 if (rv != SECSuccess)
michael@0 547 goto loser;
michael@0 548
michael@0 549 if (!ss->sec.isServer) {
michael@0 550 TLSExtensionData *xtnData = &ss->xtnData;
michael@0 551 xtnData->advertised[xtnData->numAdvertised++] =
michael@0 552 ssl_session_ticket_xtn;
michael@0 553 }
michael@0 554 } else if (maxBytes < extension_length) {
michael@0 555 PORT_Assert(0);
michael@0 556 return 0;
michael@0 557 }
michael@0 558 return extension_length;
michael@0 559
michael@0 560 loser:
michael@0 561 ss->xtnData.ticketTimestampVerified = PR_FALSE;
michael@0 562 return -1;
michael@0 563 }
michael@0 564
michael@0 565 /* handle an incoming Next Protocol Negotiation extension. */
michael@0 566 static SECStatus
michael@0 567 ssl3_ServerHandleNextProtoNegoXtn(sslSocket * ss, PRUint16 ex_type,
michael@0 568 SECItem *data)
michael@0 569 {
michael@0 570 if (ss->firstHsDone || data->len != 0) {
michael@0 571 /* Clients MUST send an empty NPN extension, if any. */
michael@0 572 PORT_SetError(SSL_ERROR_NEXT_PROTOCOL_DATA_INVALID);
michael@0 573 return SECFailure;
michael@0 574 }
michael@0 575
michael@0 576 ss->xtnData.negotiated[ss->xtnData.numNegotiated++] = ex_type;
michael@0 577
michael@0 578 /* TODO: server side NPN support would require calling
michael@0 579 * ssl3_RegisterServerHelloExtensionSender here in order to echo the
michael@0 580 * extension back to the client. */
michael@0 581
michael@0 582 return SECSuccess;
michael@0 583 }
michael@0 584
michael@0 585 /* ssl3_ValidateNextProtoNego checks that the given block of data is valid: none
michael@0 586 * of the lengths may be 0 and the sum of the lengths must equal the length of
michael@0 587 * the block. */
michael@0 588 SECStatus
michael@0 589 ssl3_ValidateNextProtoNego(const unsigned char* data, unsigned int length)
michael@0 590 {
michael@0 591 unsigned int offset = 0;
michael@0 592
michael@0 593 while (offset < length) {
michael@0 594 unsigned int newOffset = offset + 1 + (unsigned int) data[offset];
michael@0 595 /* Reject embedded nulls to protect against buggy applications that
michael@0 596 * store protocol identifiers in null-terminated strings.
michael@0 597 */
michael@0 598 if (newOffset > length || data[offset] == 0) {
michael@0 599 PORT_SetError(SSL_ERROR_NEXT_PROTOCOL_DATA_INVALID);
michael@0 600 return SECFailure;
michael@0 601 }
michael@0 602 offset = newOffset;
michael@0 603 }
michael@0 604
michael@0 605 if (offset > length) {
michael@0 606 PORT_SetError(SSL_ERROR_NEXT_PROTOCOL_DATA_INVALID);
michael@0 607 return SECFailure;
michael@0 608 }
michael@0 609
michael@0 610 return SECSuccess;
michael@0 611 }
michael@0 612
michael@0 613 /* protocol selection handler for ALPN (server side) and NPN (client side) */
michael@0 614 static SECStatus
michael@0 615 ssl3_SelectAppProtocol(sslSocket *ss, PRUint16 ex_type, SECItem *data)
michael@0 616 {
michael@0 617 SECStatus rv;
michael@0 618 unsigned char resultBuffer[255];
michael@0 619 SECItem result = { siBuffer, resultBuffer, 0 };
michael@0 620
michael@0 621 rv = ssl3_ValidateNextProtoNego(data->data, data->len);
michael@0 622 if (rv != SECSuccess)
michael@0 623 return rv;
michael@0 624
michael@0 625 PORT_Assert(ss->nextProtoCallback);
michael@0 626 rv = ss->nextProtoCallback(ss->nextProtoArg, ss->fd, data->data, data->len,
michael@0 627 result.data, &result.len, sizeof resultBuffer);
michael@0 628 if (rv != SECSuccess)
michael@0 629 return rv;
michael@0 630 /* If the callback wrote more than allowed to |result| it has corrupted our
michael@0 631 * stack. */
michael@0 632 if (result.len > sizeof resultBuffer) {
michael@0 633 PORT_SetError(SEC_ERROR_OUTPUT_LEN);
michael@0 634 return SECFailure;
michael@0 635 }
michael@0 636
michael@0 637 if (ex_type == ssl_app_layer_protocol_xtn &&
michael@0 638 ss->ssl3.nextProtoState != SSL_NEXT_PROTO_NEGOTIATED) {
michael@0 639 /* The callback might say OK, but then it's picked a default.
michael@0 640 * That's OK for NPN, but not ALPN. */
michael@0 641 SECITEM_FreeItem(&ss->ssl3.nextProto, PR_FALSE);
michael@0 642 PORT_SetError(SSL_ERROR_NEXT_PROTOCOL_NO_PROTOCOL);
michael@0 643 (void)SSL3_SendAlert(ss, alert_fatal, no_application_protocol);
michael@0 644 return SECFailure;
michael@0 645 }
michael@0 646
michael@0 647 ss->xtnData.negotiated[ss->xtnData.numNegotiated++] = ex_type;
michael@0 648
michael@0 649 SECITEM_FreeItem(&ss->ssl3.nextProto, PR_FALSE);
michael@0 650 return SECITEM_CopyItem(NULL, &ss->ssl3.nextProto, &result);
michael@0 651 }
michael@0 652
michael@0 653 /* handle an incoming ALPN extension at the server */
michael@0 654 static SECStatus
michael@0 655 ssl3_ServerHandleAppProtoXtn(sslSocket *ss, PRUint16 ex_type, SECItem *data)
michael@0 656 {
michael@0 657 int count;
michael@0 658 SECStatus rv;
michael@0 659
michael@0 660 /* We expressly don't want to allow ALPN on renegotiation,
michael@0 661 * despite it being permitted by the spec. */
michael@0 662 if (ss->firstHsDone || data->len == 0) {
michael@0 663 /* Clients MUST send a non-empty ALPN extension. */
michael@0 664 PORT_SetError(SSL_ERROR_NEXT_PROTOCOL_DATA_INVALID);
michael@0 665 return SECFailure;
michael@0 666 }
michael@0 667
michael@0 668 /* unlike NPN, ALPN has extra redundant length information so that
michael@0 669 * the extension is the same in both ClientHello and ServerHello */
michael@0 670 count = ssl3_ConsumeHandshakeNumber(ss, 2, &data->data, &data->len);
michael@0 671 if (count < 0) {
michael@0 672 return SECFailure; /* fatal alert was sent */
michael@0 673 }
michael@0 674 if (count != data->len) {
michael@0 675 return ssl3_DecodeError(ss);
michael@0 676 }
michael@0 677
michael@0 678 if (!ss->nextProtoCallback) {
michael@0 679 /* we're not configured for it */
michael@0 680 return SECSuccess;
michael@0 681 }
michael@0 682
michael@0 683 rv = ssl3_SelectAppProtocol(ss, ex_type, data);
michael@0 684 if (rv != SECSuccess) {
michael@0 685 return rv;
michael@0 686 }
michael@0 687
michael@0 688 /* prepare to send back a response, if we negotiated */
michael@0 689 if (ss->ssl3.nextProtoState == SSL_NEXT_PROTO_NEGOTIATED) {
michael@0 690 return ssl3_RegisterServerHelloExtensionSender(
michael@0 691 ss, ex_type, ssl3_ServerSendAppProtoXtn);
michael@0 692 }
michael@0 693 return SECSuccess;
michael@0 694 }
michael@0 695
michael@0 696 static SECStatus
michael@0 697 ssl3_ClientHandleNextProtoNegoXtn(sslSocket *ss, PRUint16 ex_type,
michael@0 698 SECItem *data)
michael@0 699 {
michael@0 700 PORT_Assert(!ss->firstHsDone);
michael@0 701
michael@0 702 if (ssl3_ExtensionNegotiated(ss, ssl_app_layer_protocol_xtn)) {
michael@0 703 /* If the server negotiated ALPN then it has already told us what
michael@0 704 * protocol to use, so it doesn't make sense for us to try to negotiate
michael@0 705 * a different one by sending the NPN handshake message. However, if
michael@0 706 * we've negotiated NPN then we're required to send the NPN handshake
michael@0 707 * message. Thus, these two extensions cannot both be negotiated on the
michael@0 708 * same connection. */
michael@0 709 PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
michael@0 710 return SECFailure;
michael@0 711 }
michael@0 712
michael@0 713 /* We should only get this call if we sent the extension, so
michael@0 714 * ss->nextProtoCallback needs to be non-NULL. However, it is possible
michael@0 715 * that an application erroneously cleared the callback between the time
michael@0 716 * we sent the ClientHello and now. */
michael@0 717 if (!ss->nextProtoCallback) {
michael@0 718 PORT_SetError(SSL_ERROR_NEXT_PROTOCOL_NO_CALLBACK);
michael@0 719 return SECFailure;
michael@0 720 }
michael@0 721
michael@0 722 return ssl3_SelectAppProtocol(ss, ex_type, data);
michael@0 723 }
michael@0 724
michael@0 725 static SECStatus
michael@0 726 ssl3_ClientHandleAppProtoXtn(sslSocket *ss, PRUint16 ex_type, SECItem *data)
michael@0 727 {
michael@0 728 const unsigned char* d = data->data;
michael@0 729 PRUint16 name_list_len;
michael@0 730 SECItem protocol_name;
michael@0 731
michael@0 732 if (ssl3_ExtensionNegotiated(ss, ssl_next_proto_nego_xtn)) {
michael@0 733 PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
michael@0 734 return SECFailure;
michael@0 735 }
michael@0 736
michael@0 737 /* The extension data from the server has the following format:
michael@0 738 * uint16 name_list_len;
michael@0 739 * uint8 len;
michael@0 740 * uint8 protocol_name[len]; */
michael@0 741 if (data->len < 4 || data->len > 2 + 1 + 255) {
michael@0 742 PORT_SetError(SSL_ERROR_NEXT_PROTOCOL_DATA_INVALID);
michael@0 743 return SECFailure;
michael@0 744 }
michael@0 745
michael@0 746 name_list_len = ((PRUint16) d[0]) << 8 |
michael@0 747 ((PRUint16) d[1]);
michael@0 748 if (name_list_len != data->len - 2 || d[2] != data->len - 3) {
michael@0 749 PORT_SetError(SSL_ERROR_NEXT_PROTOCOL_DATA_INVALID);
michael@0 750 return SECFailure;
michael@0 751 }
michael@0 752
michael@0 753 protocol_name.data = data->data + 3;
michael@0 754 protocol_name.len = data->len - 3;
michael@0 755
michael@0 756 SECITEM_FreeItem(&ss->ssl3.nextProto, PR_FALSE);
michael@0 757 ss->ssl3.nextProtoState = SSL_NEXT_PROTO_SELECTED;
michael@0 758 ss->xtnData.negotiated[ss->xtnData.numNegotiated++] = ex_type;
michael@0 759 return SECITEM_CopyItem(NULL, &ss->ssl3.nextProto, &protocol_name);
michael@0 760 }
michael@0 761
michael@0 762 static PRInt32
michael@0 763 ssl3_ClientSendNextProtoNegoXtn(sslSocket * ss, PRBool append,
michael@0 764 PRUint32 maxBytes)
michael@0 765 {
michael@0 766 PRInt32 extension_length;
michael@0 767
michael@0 768 /* Renegotiations do not send this extension. */
michael@0 769 if (!ss->opt.enableNPN || !ss->nextProtoCallback || ss->firstHsDone) {
michael@0 770 return 0;
michael@0 771 }
michael@0 772
michael@0 773 extension_length = 4;
michael@0 774
michael@0 775 if (append && maxBytes >= extension_length) {
michael@0 776 SECStatus rv;
michael@0 777 rv = ssl3_AppendHandshakeNumber(ss, ssl_next_proto_nego_xtn, 2);
michael@0 778 if (rv != SECSuccess)
michael@0 779 goto loser;
michael@0 780 rv = ssl3_AppendHandshakeNumber(ss, 0, 2);
michael@0 781 if (rv != SECSuccess)
michael@0 782 goto loser;
michael@0 783 ss->xtnData.advertised[ss->xtnData.numAdvertised++] =
michael@0 784 ssl_next_proto_nego_xtn;
michael@0 785 } else if (maxBytes < extension_length) {
michael@0 786 return 0;
michael@0 787 }
michael@0 788
michael@0 789 return extension_length;
michael@0 790
michael@0 791 loser:
michael@0 792 return -1;
michael@0 793 }
michael@0 794
michael@0 795 static PRInt32
michael@0 796 ssl3_ClientSendAppProtoXtn(sslSocket * ss, PRBool append, PRUint32 maxBytes)
michael@0 797 {
michael@0 798 PRInt32 extension_length;
michael@0 799 unsigned char *alpn_protos = NULL;
michael@0 800
michael@0 801 /* Renegotiations do not send this extension. */
michael@0 802 if (!ss->opt.enableALPN || !ss->opt.nextProtoNego.data || ss->firstHsDone) {
michael@0 803 return 0;
michael@0 804 }
michael@0 805
michael@0 806 extension_length = 2 /* extension type */ + 2 /* extension length */ +
michael@0 807 2 /* protocol name list length */ +
michael@0 808 ss->opt.nextProtoNego.len;
michael@0 809
michael@0 810 if (append && maxBytes >= extension_length) {
michael@0 811 /* NPN requires that the client's fallback protocol is first in the
michael@0 812 * list. However, ALPN sends protocols in preference order. So we
michael@0 813 * allocate a buffer and move the first protocol to the end of the
michael@0 814 * list. */
michael@0 815 SECStatus rv;
michael@0 816 const unsigned int len = ss->opt.nextProtoNego.len;
michael@0 817
michael@0 818 alpn_protos = PORT_Alloc(len);
michael@0 819 if (alpn_protos == NULL) {
michael@0 820 return SECFailure;
michael@0 821 }
michael@0 822 if (len > 0) {
michael@0 823 /* Each protocol string is prefixed with a single byte length. */
michael@0 824 unsigned int i = ss->opt.nextProtoNego.data[0] + 1;
michael@0 825 if (i <= len) {
michael@0 826 memcpy(alpn_protos, &ss->opt.nextProtoNego.data[i], len - i);
michael@0 827 memcpy(alpn_protos + len - i, ss->opt.nextProtoNego.data, i);
michael@0 828 } else {
michael@0 829 /* This seems to be invalid data so we'll send as-is. */
michael@0 830 memcpy(alpn_protos, ss->opt.nextProtoNego.data, len);
michael@0 831 }
michael@0 832 }
michael@0 833
michael@0 834 rv = ssl3_AppendHandshakeNumber(ss, ssl_app_layer_protocol_xtn, 2);
michael@0 835 if (rv != SECSuccess) {
michael@0 836 goto loser;
michael@0 837 }
michael@0 838 rv = ssl3_AppendHandshakeNumber(ss, extension_length - 4, 2);
michael@0 839 if (rv != SECSuccess) {
michael@0 840 goto loser;
michael@0 841 }
michael@0 842 rv = ssl3_AppendHandshakeVariable(ss, alpn_protos, len, 2);
michael@0 843 PORT_Free(alpn_protos);
michael@0 844 alpn_protos = NULL;
michael@0 845 if (rv != SECSuccess) {
michael@0 846 goto loser;
michael@0 847 }
michael@0 848 ss->xtnData.advertised[ss->xtnData.numAdvertised++] =
michael@0 849 ssl_app_layer_protocol_xtn;
michael@0 850 } else if (maxBytes < extension_length) {
michael@0 851 return 0;
michael@0 852 }
michael@0 853
michael@0 854 return extension_length;
michael@0 855
michael@0 856 loser:
michael@0 857 if (alpn_protos) {
michael@0 858 PORT_Free(alpn_protos);
michael@0 859 }
michael@0 860 return -1;
michael@0 861 }
michael@0 862
michael@0 863 static PRInt32
michael@0 864 ssl3_ServerSendAppProtoXtn(sslSocket * ss, PRBool append, PRUint32 maxBytes)
michael@0 865 {
michael@0 866 PRInt32 extension_length;
michael@0 867
michael@0 868 /* we're in over our heads if any of these fail */
michael@0 869 PORT_Assert(ss->opt.enableALPN);
michael@0 870 PORT_Assert(ss->ssl3.nextProto.data);
michael@0 871 PORT_Assert(ss->ssl3.nextProto.len > 0);
michael@0 872 PORT_Assert(ss->ssl3.nextProtoState == SSL_NEXT_PROTO_NEGOTIATED);
michael@0 873 PORT_Assert(!ss->firstHsDone);
michael@0 874
michael@0 875 extension_length = 2 /* extension type */ + 2 /* extension length */ +
michael@0 876 2 /* protocol name list */ + 1 /* name length */ +
michael@0 877 ss->ssl3.nextProto.len;
michael@0 878
michael@0 879 if (append && maxBytes >= extension_length) {
michael@0 880 SECStatus rv;
michael@0 881 rv = ssl3_AppendHandshakeNumber(ss, ssl_app_layer_protocol_xtn, 2);
michael@0 882 if (rv != SECSuccess) {
michael@0 883 return -1;
michael@0 884 }
michael@0 885 rv = ssl3_AppendHandshakeNumber(ss, extension_length - 4, 2);
michael@0 886 if (rv != SECSuccess) {
michael@0 887 return -1;
michael@0 888 }
michael@0 889 rv = ssl3_AppendHandshakeNumber(ss, ss->ssl3.nextProto.len + 1, 2);
michael@0 890 if (rv != SECSuccess) {
michael@0 891 return -1;
michael@0 892 }
michael@0 893 rv = ssl3_AppendHandshakeVariable(ss, ss->ssl3.nextProto.data,
michael@0 894 ss->ssl3.nextProto.len, 1);
michael@0 895 if (rv != SECSuccess) {
michael@0 896 return -1;
michael@0 897 }
michael@0 898 } else if (maxBytes < extension_length) {
michael@0 899 return 0;
michael@0 900 }
michael@0 901
michael@0 902 return extension_length;
michael@0 903 }
michael@0 904
michael@0 905 static SECStatus
michael@0 906 ssl3_ClientHandleStatusRequestXtn(sslSocket *ss, PRUint16 ex_type,
michael@0 907 SECItem *data)
michael@0 908 {
michael@0 909 /* The echoed extension must be empty. */
michael@0 910 if (data->len != 0)
michael@0 911 return SECFailure;
michael@0 912
michael@0 913 /* Keep track of negotiated extensions. */
michael@0 914 ss->xtnData.negotiated[ss->xtnData.numNegotiated++] = ex_type;
michael@0 915
michael@0 916 return SECSuccess;
michael@0 917 }
michael@0 918
michael@0 919 static PRInt32
michael@0 920 ssl3_ServerSendStatusRequestXtn(
michael@0 921 sslSocket * ss,
michael@0 922 PRBool append,
michael@0 923 PRUint32 maxBytes)
michael@0 924 {
michael@0 925 PRInt32 extension_length;
michael@0 926 SECStatus rv;
michael@0 927 int i;
michael@0 928 PRBool haveStatus = PR_FALSE;
michael@0 929
michael@0 930 for (i = kt_null; i < kt_kea_size; i++) {
michael@0 931 /* TODO: This is a temporary workaround.
michael@0 932 * The correct code needs to see if we have an OCSP response for
michael@0 933 * the server certificate being used, rather than if we have any
michael@0 934 * OCSP response. See also ssl3_SendCertificateStatus.
michael@0 935 */
michael@0 936 if (ss->certStatusArray[i] && ss->certStatusArray[i]->len) {
michael@0 937 haveStatus = PR_TRUE;
michael@0 938 break;
michael@0 939 }
michael@0 940 }
michael@0 941 if (!haveStatus)
michael@0 942 return 0;
michael@0 943
michael@0 944 extension_length = 2 + 2;
michael@0 945 if (append && maxBytes >= extension_length) {
michael@0 946 /* extension_type */
michael@0 947 rv = ssl3_AppendHandshakeNumber(ss, ssl_cert_status_xtn, 2);
michael@0 948 if (rv != SECSuccess)
michael@0 949 return -1;
michael@0 950 /* length of extension_data */
michael@0 951 rv = ssl3_AppendHandshakeNumber(ss, 0, 2);
michael@0 952 if (rv != SECSuccess)
michael@0 953 return -1;
michael@0 954 }
michael@0 955
michael@0 956 return extension_length;
michael@0 957 }
michael@0 958
michael@0 959 /* ssl3_ClientSendStatusRequestXtn builds the status_request extension on the
michael@0 960 * client side. See RFC 4366 section 3.6. */
michael@0 961 static PRInt32
michael@0 962 ssl3_ClientSendStatusRequestXtn(sslSocket * ss, PRBool append,
michael@0 963 PRUint32 maxBytes)
michael@0 964 {
michael@0 965 PRInt32 extension_length;
michael@0 966
michael@0 967 if (!ss->opt.enableOCSPStapling)
michael@0 968 return 0;
michael@0 969
michael@0 970 /* extension_type (2-bytes) +
michael@0 971 * length(extension_data) (2-bytes) +
michael@0 972 * status_type (1) +
michael@0 973 * responder_id_list length (2) +
michael@0 974 * request_extensions length (2)
michael@0 975 */
michael@0 976 extension_length = 9;
michael@0 977
michael@0 978 if (append && maxBytes >= extension_length) {
michael@0 979 SECStatus rv;
michael@0 980 TLSExtensionData *xtnData;
michael@0 981
michael@0 982 /* extension_type */
michael@0 983 rv = ssl3_AppendHandshakeNumber(ss, ssl_cert_status_xtn, 2);
michael@0 984 if (rv != SECSuccess)
michael@0 985 return -1;
michael@0 986 rv = ssl3_AppendHandshakeNumber(ss, extension_length - 4, 2);
michael@0 987 if (rv != SECSuccess)
michael@0 988 return -1;
michael@0 989 rv = ssl3_AppendHandshakeNumber(ss, 1 /* status_type ocsp */, 1);
michael@0 990 if (rv != SECSuccess)
michael@0 991 return -1;
michael@0 992 /* A zero length responder_id_list means that the responders are
michael@0 993 * implicitly known to the server. */
michael@0 994 rv = ssl3_AppendHandshakeNumber(ss, 0, 2);
michael@0 995 if (rv != SECSuccess)
michael@0 996 return -1;
michael@0 997 /* A zero length request_extensions means that there are no extensions.
michael@0 998 * Specifically, we don't set the id-pkix-ocsp-nonce extension. This
michael@0 999 * means that the server can replay a cached OCSP response to us. */
michael@0 1000 rv = ssl3_AppendHandshakeNumber(ss, 0, 2);
michael@0 1001 if (rv != SECSuccess)
michael@0 1002 return -1;
michael@0 1003
michael@0 1004 xtnData = &ss->xtnData;
michael@0 1005 xtnData->advertised[xtnData->numAdvertised++] = ssl_cert_status_xtn;
michael@0 1006 } else if (maxBytes < extension_length) {
michael@0 1007 PORT_Assert(0);
michael@0 1008 return 0;
michael@0 1009 }
michael@0 1010 return extension_length;
michael@0 1011 }
michael@0 1012
michael@0 1013 /*
michael@0 1014 * NewSessionTicket
michael@0 1015 * Called from ssl3_HandleFinished
michael@0 1016 */
michael@0 1017 SECStatus
michael@0 1018 ssl3_SendNewSessionTicket(sslSocket *ss)
michael@0 1019 {
michael@0 1020 int i;
michael@0 1021 SECStatus rv;
michael@0 1022 NewSessionTicket ticket;
michael@0 1023 SECItem plaintext;
michael@0 1024 SECItem plaintext_item = {0, NULL, 0};
michael@0 1025 SECItem ciphertext = {0, NULL, 0};
michael@0 1026 PRUint32 ciphertext_length;
michael@0 1027 PRBool ms_is_wrapped;
michael@0 1028 unsigned char wrapped_ms[SSL3_MASTER_SECRET_LENGTH];
michael@0 1029 SECItem ms_item = {0, NULL, 0};
michael@0 1030 SSL3KEAType effectiveExchKeyType = ssl_kea_null;
michael@0 1031 PRUint32 padding_length;
michael@0 1032 PRUint32 message_length;
michael@0 1033 PRUint32 cert_length;
michael@0 1034 PRUint8 length_buf[4];
michael@0 1035 PRUint32 now;
michael@0 1036 PK11SymKey *aes_key_pkcs11;
michael@0 1037 PK11SymKey *mac_key_pkcs11;
michael@0 1038 #ifndef NO_PKCS11_BYPASS
michael@0 1039 const unsigned char *aes_key;
michael@0 1040 const unsigned char *mac_key;
michael@0 1041 PRUint32 aes_key_length;
michael@0 1042 PRUint32 mac_key_length;
michael@0 1043 PRUint64 aes_ctx_buf[MAX_CIPHER_CONTEXT_LLONGS];
michael@0 1044 AESContext *aes_ctx;
michael@0 1045 const SECHashObject *hashObj = NULL;
michael@0 1046 PRUint64 hmac_ctx_buf[MAX_MAC_CONTEXT_LLONGS];
michael@0 1047 HMACContext *hmac_ctx;
michael@0 1048 #endif
michael@0 1049 CK_MECHANISM_TYPE cipherMech = CKM_AES_CBC;
michael@0 1050 PK11Context *aes_ctx_pkcs11;
michael@0 1051 CK_MECHANISM_TYPE macMech = CKM_SHA256_HMAC;
michael@0 1052 PK11Context *hmac_ctx_pkcs11;
michael@0 1053 unsigned char computed_mac[TLS_EX_SESS_TICKET_MAC_LENGTH];
michael@0 1054 unsigned int computed_mac_length;
michael@0 1055 unsigned char iv[AES_BLOCK_SIZE];
michael@0 1056 SECItem ivItem;
michael@0 1057 SECItem *srvName = NULL;
michael@0 1058 PRUint32 srvNameLen = 0;
michael@0 1059 CK_MECHANISM_TYPE msWrapMech = 0; /* dummy default value,
michael@0 1060 * must be >= 0 */
michael@0 1061
michael@0 1062 SSL_TRC(3, ("%d: SSL3[%d]: send session_ticket handshake",
michael@0 1063 SSL_GETPID(), ss->fd));
michael@0 1064
michael@0 1065 PORT_Assert( ss->opt.noLocks || ssl_HaveXmitBufLock(ss));
michael@0 1066 PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss));
michael@0 1067
michael@0 1068 ticket.ticket_lifetime_hint = TLS_EX_SESS_TICKET_LIFETIME_HINT;
michael@0 1069 cert_length = (ss->opt.requestCertificate && ss->sec.ci.sid->peerCert) ?
michael@0 1070 3 + ss->sec.ci.sid->peerCert->derCert.len : 0;
michael@0 1071
michael@0 1072 /* Get IV and encryption keys */
michael@0 1073 ivItem.data = iv;
michael@0 1074 ivItem.len = sizeof(iv);
michael@0 1075 rv = PK11_GenerateRandom(iv, sizeof(iv));
michael@0 1076 if (rv != SECSuccess) goto loser;
michael@0 1077
michael@0 1078 #ifndef NO_PKCS11_BYPASS
michael@0 1079 if (ss->opt.bypassPKCS11) {
michael@0 1080 rv = ssl3_GetSessionTicketKeys(&aes_key, &aes_key_length,
michael@0 1081 &mac_key, &mac_key_length);
michael@0 1082 } else
michael@0 1083 #endif
michael@0 1084 {
michael@0 1085 rv = ssl3_GetSessionTicketKeysPKCS11(ss, &aes_key_pkcs11,
michael@0 1086 &mac_key_pkcs11);
michael@0 1087 }
michael@0 1088 if (rv != SECSuccess) goto loser;
michael@0 1089
michael@0 1090 if (ss->ssl3.pwSpec->msItem.len && ss->ssl3.pwSpec->msItem.data) {
michael@0 1091 /* The master secret is available unwrapped. */
michael@0 1092 ms_item.data = ss->ssl3.pwSpec->msItem.data;
michael@0 1093 ms_item.len = ss->ssl3.pwSpec->msItem.len;
michael@0 1094 ms_is_wrapped = PR_FALSE;
michael@0 1095 } else {
michael@0 1096 /* Extract the master secret wrapped. */
michael@0 1097 sslSessionID sid;
michael@0 1098 PORT_Memset(&sid, 0, sizeof(sslSessionID));
michael@0 1099
michael@0 1100 if (ss->ssl3.hs.kea_def->kea == kea_ecdhe_rsa) {
michael@0 1101 effectiveExchKeyType = kt_rsa;
michael@0 1102 } else {
michael@0 1103 effectiveExchKeyType = ss->ssl3.hs.kea_def->exchKeyType;
michael@0 1104 }
michael@0 1105
michael@0 1106 rv = ssl3_CacheWrappedMasterSecret(ss, &sid, ss->ssl3.pwSpec,
michael@0 1107 effectiveExchKeyType);
michael@0 1108 if (rv == SECSuccess) {
michael@0 1109 if (sid.u.ssl3.keys.wrapped_master_secret_len > sizeof(wrapped_ms))
michael@0 1110 goto loser;
michael@0 1111 memcpy(wrapped_ms, sid.u.ssl3.keys.wrapped_master_secret,
michael@0 1112 sid.u.ssl3.keys.wrapped_master_secret_len);
michael@0 1113 ms_item.data = wrapped_ms;
michael@0 1114 ms_item.len = sid.u.ssl3.keys.wrapped_master_secret_len;
michael@0 1115 msWrapMech = sid.u.ssl3.masterWrapMech;
michael@0 1116 } else {
michael@0 1117 /* TODO: else send an empty ticket. */
michael@0 1118 goto loser;
michael@0 1119 }
michael@0 1120 ms_is_wrapped = PR_TRUE;
michael@0 1121 }
michael@0 1122 /* Prep to send negotiated name */
michael@0 1123 srvName = &ss->ssl3.pwSpec->srvVirtName;
michael@0 1124 if (srvName->data && srvName->len) {
michael@0 1125 srvNameLen = 2 + srvName->len; /* len bytes + name len */
michael@0 1126 }
michael@0 1127
michael@0 1128 ciphertext_length =
michael@0 1129 sizeof(PRUint16) /* ticket_version */
michael@0 1130 + sizeof(SSL3ProtocolVersion) /* ssl_version */
michael@0 1131 + sizeof(ssl3CipherSuite) /* ciphersuite */
michael@0 1132 + 1 /* compression */
michael@0 1133 + 10 /* cipher spec parameters */
michael@0 1134 + 1 /* SessionTicket.ms_is_wrapped */
michael@0 1135 + 1 /* effectiveExchKeyType */
michael@0 1136 + 4 /* msWrapMech */
michael@0 1137 + 2 /* master_secret.length */
michael@0 1138 + ms_item.len /* master_secret */
michael@0 1139 + 1 /* client_auth_type */
michael@0 1140 + cert_length /* cert */
michael@0 1141 + 1 /* server name type */
michael@0 1142 + srvNameLen /* name len + length field */
michael@0 1143 + sizeof(ticket.ticket_lifetime_hint);
michael@0 1144 padding_length = AES_BLOCK_SIZE -
michael@0 1145 (ciphertext_length % AES_BLOCK_SIZE);
michael@0 1146 ciphertext_length += padding_length;
michael@0 1147
michael@0 1148 message_length =
michael@0 1149 sizeof(ticket.ticket_lifetime_hint) /* ticket_lifetime_hint */
michael@0 1150 + 2 /* length field for NewSessionTicket.ticket */
michael@0 1151 + SESS_TICKET_KEY_NAME_LEN /* key_name */
michael@0 1152 + AES_BLOCK_SIZE /* iv */
michael@0 1153 + 2 /* length field for NewSessionTicket.ticket.encrypted_state */
michael@0 1154 + ciphertext_length /* encrypted_state */
michael@0 1155 + TLS_EX_SESS_TICKET_MAC_LENGTH; /* mac */
michael@0 1156
michael@0 1157 if (SECITEM_AllocItem(NULL, &plaintext_item, ciphertext_length) == NULL)
michael@0 1158 goto loser;
michael@0 1159
michael@0 1160 plaintext = plaintext_item;
michael@0 1161
michael@0 1162 /* ticket_version */
michael@0 1163 rv = ssl3_AppendNumberToItem(&plaintext, TLS_EX_SESS_TICKET_VERSION,
michael@0 1164 sizeof(PRUint16));
michael@0 1165 if (rv != SECSuccess) goto loser;
michael@0 1166
michael@0 1167 /* ssl_version */
michael@0 1168 rv = ssl3_AppendNumberToItem(&plaintext, ss->version,
michael@0 1169 sizeof(SSL3ProtocolVersion));
michael@0 1170 if (rv != SECSuccess) goto loser;
michael@0 1171
michael@0 1172 /* ciphersuite */
michael@0 1173 rv = ssl3_AppendNumberToItem(&plaintext, ss->ssl3.hs.cipher_suite,
michael@0 1174 sizeof(ssl3CipherSuite));
michael@0 1175 if (rv != SECSuccess) goto loser;
michael@0 1176
michael@0 1177 /* compression */
michael@0 1178 rv = ssl3_AppendNumberToItem(&plaintext, ss->ssl3.hs.compression, 1);
michael@0 1179 if (rv != SECSuccess) goto loser;
michael@0 1180
michael@0 1181 /* cipher spec parameters */
michael@0 1182 rv = ssl3_AppendNumberToItem(&plaintext, ss->sec.authAlgorithm, 1);
michael@0 1183 if (rv != SECSuccess) goto loser;
michael@0 1184 rv = ssl3_AppendNumberToItem(&plaintext, ss->sec.authKeyBits, 4);
michael@0 1185 if (rv != SECSuccess) goto loser;
michael@0 1186 rv = ssl3_AppendNumberToItem(&plaintext, ss->sec.keaType, 1);
michael@0 1187 if (rv != SECSuccess) goto loser;
michael@0 1188 rv = ssl3_AppendNumberToItem(&plaintext, ss->sec.keaKeyBits, 4);
michael@0 1189 if (rv != SECSuccess) goto loser;
michael@0 1190
michael@0 1191 /* master_secret */
michael@0 1192 rv = ssl3_AppendNumberToItem(&plaintext, ms_is_wrapped, 1);
michael@0 1193 if (rv != SECSuccess) goto loser;
michael@0 1194 rv = ssl3_AppendNumberToItem(&plaintext, effectiveExchKeyType, 1);
michael@0 1195 if (rv != SECSuccess) goto loser;
michael@0 1196 rv = ssl3_AppendNumberToItem(&plaintext, msWrapMech, 4);
michael@0 1197 if (rv != SECSuccess) goto loser;
michael@0 1198 rv = ssl3_AppendNumberToItem(&plaintext, ms_item.len, 2);
michael@0 1199 if (rv != SECSuccess) goto loser;
michael@0 1200 rv = ssl3_AppendToItem(&plaintext, ms_item.data, ms_item.len);
michael@0 1201 if (rv != SECSuccess) goto loser;
michael@0 1202
michael@0 1203 /* client_identity */
michael@0 1204 if (ss->opt.requestCertificate && ss->sec.ci.sid->peerCert) {
michael@0 1205 rv = ssl3_AppendNumberToItem(&plaintext, CLIENT_AUTH_CERTIFICATE, 1);
michael@0 1206 if (rv != SECSuccess) goto loser;
michael@0 1207 rv = ssl3_AppendNumberToItem(&plaintext,
michael@0 1208 ss->sec.ci.sid->peerCert->derCert.len, 3);
michael@0 1209 if (rv != SECSuccess) goto loser;
michael@0 1210 rv = ssl3_AppendToItem(&plaintext,
michael@0 1211 ss->sec.ci.sid->peerCert->derCert.data,
michael@0 1212 ss->sec.ci.sid->peerCert->derCert.len);
michael@0 1213 if (rv != SECSuccess) goto loser;
michael@0 1214 } else {
michael@0 1215 rv = ssl3_AppendNumberToItem(&plaintext, 0, 1);
michael@0 1216 if (rv != SECSuccess) goto loser;
michael@0 1217 }
michael@0 1218
michael@0 1219 /* timestamp */
michael@0 1220 now = ssl_Time();
michael@0 1221 rv = ssl3_AppendNumberToItem(&plaintext, now,
michael@0 1222 sizeof(ticket.ticket_lifetime_hint));
michael@0 1223 if (rv != SECSuccess) goto loser;
michael@0 1224
michael@0 1225 if (srvNameLen) {
michael@0 1226 /* Name Type (sni_host_name) */
michael@0 1227 rv = ssl3_AppendNumberToItem(&plaintext, srvName->type, 1);
michael@0 1228 if (rv != SECSuccess) goto loser;
michael@0 1229 /* HostName (length and value) */
michael@0 1230 rv = ssl3_AppendNumberToItem(&plaintext, srvName->len, 2);
michael@0 1231 if (rv != SECSuccess) goto loser;
michael@0 1232 rv = ssl3_AppendToItem(&plaintext, srvName->data, srvName->len);
michael@0 1233 if (rv != SECSuccess) goto loser;
michael@0 1234 } else {
michael@0 1235 /* No Name */
michael@0 1236 rv = ssl3_AppendNumberToItem(&plaintext, (char)TLS_STE_NO_SERVER_NAME,
michael@0 1237 1);
michael@0 1238 if (rv != SECSuccess) goto loser;
michael@0 1239 }
michael@0 1240
michael@0 1241 PORT_Assert(plaintext.len == padding_length);
michael@0 1242 for (i = 0; i < padding_length; i++)
michael@0 1243 plaintext.data[i] = (unsigned char)padding_length;
michael@0 1244
michael@0 1245 if (SECITEM_AllocItem(NULL, &ciphertext, ciphertext_length) == NULL) {
michael@0 1246 rv = SECFailure;
michael@0 1247 goto loser;
michael@0 1248 }
michael@0 1249
michael@0 1250 /* Generate encrypted portion of ticket. */
michael@0 1251 #ifndef NO_PKCS11_BYPASS
michael@0 1252 if (ss->opt.bypassPKCS11) {
michael@0 1253 aes_ctx = (AESContext *)aes_ctx_buf;
michael@0 1254 rv = AES_InitContext(aes_ctx, aes_key, aes_key_length, iv,
michael@0 1255 NSS_AES_CBC, 1, AES_BLOCK_SIZE);
michael@0 1256 if (rv != SECSuccess) goto loser;
michael@0 1257
michael@0 1258 rv = AES_Encrypt(aes_ctx, ciphertext.data, &ciphertext.len,
michael@0 1259 ciphertext.len, plaintext_item.data,
michael@0 1260 plaintext_item.len);
michael@0 1261 if (rv != SECSuccess) goto loser;
michael@0 1262 } else
michael@0 1263 #endif
michael@0 1264 {
michael@0 1265 aes_ctx_pkcs11 = PK11_CreateContextBySymKey(cipherMech,
michael@0 1266 CKA_ENCRYPT, aes_key_pkcs11, &ivItem);
michael@0 1267 if (!aes_ctx_pkcs11)
michael@0 1268 goto loser;
michael@0 1269
michael@0 1270 rv = PK11_CipherOp(aes_ctx_pkcs11, ciphertext.data,
michael@0 1271 (int *)&ciphertext.len, ciphertext.len,
michael@0 1272 plaintext_item.data, plaintext_item.len);
michael@0 1273 PK11_Finalize(aes_ctx_pkcs11);
michael@0 1274 PK11_DestroyContext(aes_ctx_pkcs11, PR_TRUE);
michael@0 1275 if (rv != SECSuccess) goto loser;
michael@0 1276 }
michael@0 1277
michael@0 1278 /* Convert ciphertext length to network order. */
michael@0 1279 length_buf[0] = (ciphertext.len >> 8) & 0xff;
michael@0 1280 length_buf[1] = (ciphertext.len ) & 0xff;
michael@0 1281
michael@0 1282 /* Compute MAC. */
michael@0 1283 #ifndef NO_PKCS11_BYPASS
michael@0 1284 if (ss->opt.bypassPKCS11) {
michael@0 1285 hmac_ctx = (HMACContext *)hmac_ctx_buf;
michael@0 1286 hashObj = HASH_GetRawHashObject(HASH_AlgSHA256);
michael@0 1287 if (HMAC_Init(hmac_ctx, hashObj, mac_key,
michael@0 1288 mac_key_length, PR_FALSE) != SECSuccess)
michael@0 1289 goto loser;
michael@0 1290
michael@0 1291 HMAC_Begin(hmac_ctx);
michael@0 1292 HMAC_Update(hmac_ctx, key_name, SESS_TICKET_KEY_NAME_LEN);
michael@0 1293 HMAC_Update(hmac_ctx, iv, sizeof(iv));
michael@0 1294 HMAC_Update(hmac_ctx, (unsigned char *)length_buf, 2);
michael@0 1295 HMAC_Update(hmac_ctx, ciphertext.data, ciphertext.len);
michael@0 1296 HMAC_Finish(hmac_ctx, computed_mac, &computed_mac_length,
michael@0 1297 sizeof(computed_mac));
michael@0 1298 } else
michael@0 1299 #endif
michael@0 1300 {
michael@0 1301 SECItem macParam;
michael@0 1302 macParam.data = NULL;
michael@0 1303 macParam.len = 0;
michael@0 1304 hmac_ctx_pkcs11 = PK11_CreateContextBySymKey(macMech,
michael@0 1305 CKA_SIGN, mac_key_pkcs11, &macParam);
michael@0 1306 if (!hmac_ctx_pkcs11)
michael@0 1307 goto loser;
michael@0 1308
michael@0 1309 rv = PK11_DigestBegin(hmac_ctx_pkcs11);
michael@0 1310 rv = PK11_DigestOp(hmac_ctx_pkcs11, key_name,
michael@0 1311 SESS_TICKET_KEY_NAME_LEN);
michael@0 1312 rv = PK11_DigestOp(hmac_ctx_pkcs11, iv, sizeof(iv));
michael@0 1313 rv = PK11_DigestOp(hmac_ctx_pkcs11, (unsigned char *)length_buf, 2);
michael@0 1314 rv = PK11_DigestOp(hmac_ctx_pkcs11, ciphertext.data, ciphertext.len);
michael@0 1315 rv = PK11_DigestFinal(hmac_ctx_pkcs11, computed_mac,
michael@0 1316 &computed_mac_length, sizeof(computed_mac));
michael@0 1317 PK11_DestroyContext(hmac_ctx_pkcs11, PR_TRUE);
michael@0 1318 if (rv != SECSuccess) goto loser;
michael@0 1319 }
michael@0 1320
michael@0 1321 /* Serialize the handshake message. */
michael@0 1322 rv = ssl3_AppendHandshakeHeader(ss, new_session_ticket, message_length);
michael@0 1323 if (rv != SECSuccess) goto loser;
michael@0 1324
michael@0 1325 rv = ssl3_AppendHandshakeNumber(ss, ticket.ticket_lifetime_hint,
michael@0 1326 sizeof(ticket.ticket_lifetime_hint));
michael@0 1327 if (rv != SECSuccess) goto loser;
michael@0 1328
michael@0 1329 rv = ssl3_AppendHandshakeNumber(ss,
michael@0 1330 message_length - sizeof(ticket.ticket_lifetime_hint) - 2, 2);
michael@0 1331 if (rv != SECSuccess) goto loser;
michael@0 1332
michael@0 1333 rv = ssl3_AppendHandshake(ss, key_name, SESS_TICKET_KEY_NAME_LEN);
michael@0 1334 if (rv != SECSuccess) goto loser;
michael@0 1335
michael@0 1336 rv = ssl3_AppendHandshake(ss, iv, sizeof(iv));
michael@0 1337 if (rv != SECSuccess) goto loser;
michael@0 1338
michael@0 1339 rv = ssl3_AppendHandshakeVariable(ss, ciphertext.data, ciphertext.len, 2);
michael@0 1340 if (rv != SECSuccess) goto loser;
michael@0 1341
michael@0 1342 rv = ssl3_AppendHandshake(ss, computed_mac, computed_mac_length);
michael@0 1343 if (rv != SECSuccess) goto loser;
michael@0 1344
michael@0 1345 loser:
michael@0 1346 if (plaintext_item.data)
michael@0 1347 SECITEM_FreeItem(&plaintext_item, PR_FALSE);
michael@0 1348 if (ciphertext.data)
michael@0 1349 SECITEM_FreeItem(&ciphertext, PR_FALSE);
michael@0 1350
michael@0 1351 return rv;
michael@0 1352 }
michael@0 1353
michael@0 1354 /* When a client receives a SessionTicket extension a NewSessionTicket
michael@0 1355 * message is expected during the handshake.
michael@0 1356 */
michael@0 1357 SECStatus
michael@0 1358 ssl3_ClientHandleSessionTicketXtn(sslSocket *ss, PRUint16 ex_type,
michael@0 1359 SECItem *data)
michael@0 1360 {
michael@0 1361 if (data->len != 0)
michael@0 1362 return SECFailure;
michael@0 1363
michael@0 1364 /* Keep track of negotiated extensions. */
michael@0 1365 ss->xtnData.negotiated[ss->xtnData.numNegotiated++] = ex_type;
michael@0 1366 return SECSuccess;
michael@0 1367 }
michael@0 1368
michael@0 1369 SECStatus
michael@0 1370 ssl3_ServerHandleSessionTicketXtn(sslSocket *ss, PRUint16 ex_type,
michael@0 1371 SECItem *data)
michael@0 1372 {
michael@0 1373 SECStatus rv;
michael@0 1374 SECItem *decrypted_state = NULL;
michael@0 1375 SessionTicket *parsed_session_ticket = NULL;
michael@0 1376 sslSessionID *sid = NULL;
michael@0 1377 SSL3Statistics *ssl3stats;
michael@0 1378
michael@0 1379 /* Ignore the SessionTicket extension if processing is disabled. */
michael@0 1380 if (!ss->opt.enableSessionTickets)
michael@0 1381 return SECSuccess;
michael@0 1382
michael@0 1383 /* Keep track of negotiated extensions. */
michael@0 1384 ss->xtnData.negotiated[ss->xtnData.numNegotiated++] = ex_type;
michael@0 1385
michael@0 1386 /* Parse the received ticket sent in by the client. We are
michael@0 1387 * lenient about some parse errors, falling back to a fullshake
michael@0 1388 * instead of terminating the current connection.
michael@0 1389 */
michael@0 1390 if (data->len == 0) {
michael@0 1391 ss->xtnData.emptySessionTicket = PR_TRUE;
michael@0 1392 } else {
michael@0 1393 int i;
michael@0 1394 SECItem extension_data;
michael@0 1395 EncryptedSessionTicket enc_session_ticket;
michael@0 1396 unsigned char computed_mac[TLS_EX_SESS_TICKET_MAC_LENGTH];
michael@0 1397 unsigned int computed_mac_length;
michael@0 1398 #ifndef NO_PKCS11_BYPASS
michael@0 1399 const SECHashObject *hashObj;
michael@0 1400 const unsigned char *aes_key;
michael@0 1401 const unsigned char *mac_key;
michael@0 1402 PRUint32 aes_key_length;
michael@0 1403 PRUint32 mac_key_length;
michael@0 1404 PRUint64 hmac_ctx_buf[MAX_MAC_CONTEXT_LLONGS];
michael@0 1405 HMACContext *hmac_ctx;
michael@0 1406 PRUint64 aes_ctx_buf[MAX_CIPHER_CONTEXT_LLONGS];
michael@0 1407 AESContext *aes_ctx;
michael@0 1408 #endif
michael@0 1409 PK11SymKey *aes_key_pkcs11;
michael@0 1410 PK11SymKey *mac_key_pkcs11;
michael@0 1411 PK11Context *hmac_ctx_pkcs11;
michael@0 1412 CK_MECHANISM_TYPE macMech = CKM_SHA256_HMAC;
michael@0 1413 PK11Context *aes_ctx_pkcs11;
michael@0 1414 CK_MECHANISM_TYPE cipherMech = CKM_AES_CBC;
michael@0 1415 unsigned char * padding;
michael@0 1416 PRUint32 padding_length;
michael@0 1417 unsigned char *buffer;
michael@0 1418 unsigned int buffer_len;
michael@0 1419 PRInt32 temp;
michael@0 1420 SECItem cert_item;
michael@0 1421 PRInt8 nameType = TLS_STE_NO_SERVER_NAME;
michael@0 1422
michael@0 1423 /* Turn off stateless session resumption if the client sends a
michael@0 1424 * SessionTicket extension, even if the extension turns out to be
michael@0 1425 * malformed (ss->sec.ci.sid is non-NULL when doing session
michael@0 1426 * renegotiation.)
michael@0 1427 */
michael@0 1428 if (ss->sec.ci.sid != NULL) {
michael@0 1429 if (ss->sec.uncache)
michael@0 1430 ss->sec.uncache(ss->sec.ci.sid);
michael@0 1431 ssl_FreeSID(ss->sec.ci.sid);
michael@0 1432 ss->sec.ci.sid = NULL;
michael@0 1433 }
michael@0 1434
michael@0 1435 extension_data.data = data->data; /* Keep a copy for future use. */
michael@0 1436 extension_data.len = data->len;
michael@0 1437
michael@0 1438 if (ssl3_ParseEncryptedSessionTicket(ss, data, &enc_session_ticket)
michael@0 1439 != SECSuccess)
michael@0 1440 return SECFailure;
michael@0 1441
michael@0 1442 /* Get session ticket keys. */
michael@0 1443 #ifndef NO_PKCS11_BYPASS
michael@0 1444 if (ss->opt.bypassPKCS11) {
michael@0 1445 rv = ssl3_GetSessionTicketKeys(&aes_key, &aes_key_length,
michael@0 1446 &mac_key, &mac_key_length);
michael@0 1447 } else
michael@0 1448 #endif
michael@0 1449 {
michael@0 1450 rv = ssl3_GetSessionTicketKeysPKCS11(ss, &aes_key_pkcs11,
michael@0 1451 &mac_key_pkcs11);
michael@0 1452 }
michael@0 1453 if (rv != SECSuccess) {
michael@0 1454 SSL_DBG(("%d: SSL[%d]: Unable to get/generate session ticket keys.",
michael@0 1455 SSL_GETPID(), ss->fd));
michael@0 1456 goto loser;
michael@0 1457 }
michael@0 1458
michael@0 1459 /* If the ticket sent by the client was generated under a key different
michael@0 1460 * from the one we have, bypass ticket processing.
michael@0 1461 */
michael@0 1462 if (PORT_Memcmp(enc_session_ticket.key_name, key_name,
michael@0 1463 SESS_TICKET_KEY_NAME_LEN) != 0) {
michael@0 1464 SSL_DBG(("%d: SSL[%d]: Session ticket key_name sent mismatch.",
michael@0 1465 SSL_GETPID(), ss->fd));
michael@0 1466 goto no_ticket;
michael@0 1467 }
michael@0 1468
michael@0 1469 /* Verify the MAC on the ticket. MAC verification may also
michael@0 1470 * fail if the MAC key has been recently refreshed.
michael@0 1471 */
michael@0 1472 #ifndef NO_PKCS11_BYPASS
michael@0 1473 if (ss->opt.bypassPKCS11) {
michael@0 1474 hmac_ctx = (HMACContext *)hmac_ctx_buf;
michael@0 1475 hashObj = HASH_GetRawHashObject(HASH_AlgSHA256);
michael@0 1476 if (HMAC_Init(hmac_ctx, hashObj, mac_key,
michael@0 1477 sizeof(session_ticket_mac_key), PR_FALSE) != SECSuccess)
michael@0 1478 goto no_ticket;
michael@0 1479 HMAC_Begin(hmac_ctx);
michael@0 1480 HMAC_Update(hmac_ctx, extension_data.data,
michael@0 1481 extension_data.len - TLS_EX_SESS_TICKET_MAC_LENGTH);
michael@0 1482 if (HMAC_Finish(hmac_ctx, computed_mac, &computed_mac_length,
michael@0 1483 sizeof(computed_mac)) != SECSuccess)
michael@0 1484 goto no_ticket;
michael@0 1485 } else
michael@0 1486 #endif
michael@0 1487 {
michael@0 1488 SECItem macParam;
michael@0 1489 macParam.data = NULL;
michael@0 1490 macParam.len = 0;
michael@0 1491 hmac_ctx_pkcs11 = PK11_CreateContextBySymKey(macMech,
michael@0 1492 CKA_SIGN, mac_key_pkcs11, &macParam);
michael@0 1493 if (!hmac_ctx_pkcs11) {
michael@0 1494 SSL_DBG(("%d: SSL[%d]: Unable to create HMAC context: %d.",
michael@0 1495 SSL_GETPID(), ss->fd, PORT_GetError()));
michael@0 1496 goto no_ticket;
michael@0 1497 } else {
michael@0 1498 SSL_DBG(("%d: SSL[%d]: Successfully created HMAC context.",
michael@0 1499 SSL_GETPID(), ss->fd));
michael@0 1500 }
michael@0 1501 rv = PK11_DigestBegin(hmac_ctx_pkcs11);
michael@0 1502 rv = PK11_DigestOp(hmac_ctx_pkcs11, extension_data.data,
michael@0 1503 extension_data.len - TLS_EX_SESS_TICKET_MAC_LENGTH);
michael@0 1504 if (rv != SECSuccess) {
michael@0 1505 PK11_DestroyContext(hmac_ctx_pkcs11, PR_TRUE);
michael@0 1506 goto no_ticket;
michael@0 1507 }
michael@0 1508 rv = PK11_DigestFinal(hmac_ctx_pkcs11, computed_mac,
michael@0 1509 &computed_mac_length, sizeof(computed_mac));
michael@0 1510 PK11_DestroyContext(hmac_ctx_pkcs11, PR_TRUE);
michael@0 1511 if (rv != SECSuccess)
michael@0 1512 goto no_ticket;
michael@0 1513 }
michael@0 1514 if (NSS_SecureMemcmp(computed_mac, enc_session_ticket.mac,
michael@0 1515 computed_mac_length) != 0) {
michael@0 1516 SSL_DBG(("%d: SSL[%d]: Session ticket MAC mismatch.",
michael@0 1517 SSL_GETPID(), ss->fd));
michael@0 1518 goto no_ticket;
michael@0 1519 }
michael@0 1520
michael@0 1521 /* We ignore key_name for now.
michael@0 1522 * This is ok as MAC verification succeeded.
michael@0 1523 */
michael@0 1524
michael@0 1525 /* Decrypt the ticket. */
michael@0 1526
michael@0 1527 /* Plaintext is shorter than the ciphertext due to padding. */
michael@0 1528 decrypted_state = SECITEM_AllocItem(NULL, NULL,
michael@0 1529 enc_session_ticket.encrypted_state.len);
michael@0 1530
michael@0 1531 #ifndef NO_PKCS11_BYPASS
michael@0 1532 if (ss->opt.bypassPKCS11) {
michael@0 1533 aes_ctx = (AESContext *)aes_ctx_buf;
michael@0 1534 rv = AES_InitContext(aes_ctx, aes_key,
michael@0 1535 sizeof(session_ticket_enc_key), enc_session_ticket.iv,
michael@0 1536 NSS_AES_CBC, 0,AES_BLOCK_SIZE);
michael@0 1537 if (rv != SECSuccess) {
michael@0 1538 SSL_DBG(("%d: SSL[%d]: Unable to create AES context.",
michael@0 1539 SSL_GETPID(), ss->fd));
michael@0 1540 goto no_ticket;
michael@0 1541 }
michael@0 1542
michael@0 1543 rv = AES_Decrypt(aes_ctx, decrypted_state->data,
michael@0 1544 &decrypted_state->len, decrypted_state->len,
michael@0 1545 enc_session_ticket.encrypted_state.data,
michael@0 1546 enc_session_ticket.encrypted_state.len);
michael@0 1547 if (rv != SECSuccess)
michael@0 1548 goto no_ticket;
michael@0 1549 } else
michael@0 1550 #endif
michael@0 1551 {
michael@0 1552 SECItem ivItem;
michael@0 1553 ivItem.data = enc_session_ticket.iv;
michael@0 1554 ivItem.len = AES_BLOCK_SIZE;
michael@0 1555 aes_ctx_pkcs11 = PK11_CreateContextBySymKey(cipherMech,
michael@0 1556 CKA_DECRYPT, aes_key_pkcs11, &ivItem);
michael@0 1557 if (!aes_ctx_pkcs11) {
michael@0 1558 SSL_DBG(("%d: SSL[%d]: Unable to create AES context.",
michael@0 1559 SSL_GETPID(), ss->fd));
michael@0 1560 goto no_ticket;
michael@0 1561 }
michael@0 1562
michael@0 1563 rv = PK11_CipherOp(aes_ctx_pkcs11, decrypted_state->data,
michael@0 1564 (int *)&decrypted_state->len, decrypted_state->len,
michael@0 1565 enc_session_ticket.encrypted_state.data,
michael@0 1566 enc_session_ticket.encrypted_state.len);
michael@0 1567 PK11_Finalize(aes_ctx_pkcs11);
michael@0 1568 PK11_DestroyContext(aes_ctx_pkcs11, PR_TRUE);
michael@0 1569 if (rv != SECSuccess)
michael@0 1570 goto no_ticket;
michael@0 1571 }
michael@0 1572
michael@0 1573 /* Check padding. */
michael@0 1574 padding_length =
michael@0 1575 (PRUint32)decrypted_state->data[decrypted_state->len - 1];
michael@0 1576 if (padding_length == 0 || padding_length > AES_BLOCK_SIZE)
michael@0 1577 goto no_ticket;
michael@0 1578
michael@0 1579 padding = &decrypted_state->data[decrypted_state->len - padding_length];
michael@0 1580 for (i = 0; i < padding_length; i++, padding++) {
michael@0 1581 if (padding_length != (PRUint32)*padding)
michael@0 1582 goto no_ticket;
michael@0 1583 }
michael@0 1584
michael@0 1585 /* Deserialize session state. */
michael@0 1586 buffer = decrypted_state->data;
michael@0 1587 buffer_len = decrypted_state->len;
michael@0 1588
michael@0 1589 parsed_session_ticket = PORT_ZAlloc(sizeof(SessionTicket));
michael@0 1590 if (parsed_session_ticket == NULL) {
michael@0 1591 rv = SECFailure;
michael@0 1592 goto loser;
michael@0 1593 }
michael@0 1594
michael@0 1595 /* Read ticket_version (which is ignored for now.) */
michael@0 1596 temp = ssl3_ConsumeHandshakeNumber(ss, 2, &buffer, &buffer_len);
michael@0 1597 if (temp < 0) goto no_ticket;
michael@0 1598 parsed_session_ticket->ticket_version = (SSL3ProtocolVersion)temp;
michael@0 1599
michael@0 1600 /* Read SSLVersion. */
michael@0 1601 temp = ssl3_ConsumeHandshakeNumber(ss, 2, &buffer, &buffer_len);
michael@0 1602 if (temp < 0) goto no_ticket;
michael@0 1603 parsed_session_ticket->ssl_version = (SSL3ProtocolVersion)temp;
michael@0 1604
michael@0 1605 /* Read cipher_suite. */
michael@0 1606 temp = ssl3_ConsumeHandshakeNumber(ss, 2, &buffer, &buffer_len);
michael@0 1607 if (temp < 0) goto no_ticket;
michael@0 1608 parsed_session_ticket->cipher_suite = (ssl3CipherSuite)temp;
michael@0 1609
michael@0 1610 /* Read compression_method. */
michael@0 1611 temp = ssl3_ConsumeHandshakeNumber(ss, 1, &buffer, &buffer_len);
michael@0 1612 if (temp < 0) goto no_ticket;
michael@0 1613 parsed_session_ticket->compression_method = (SSLCompressionMethod)temp;
michael@0 1614
michael@0 1615 /* Read cipher spec parameters. */
michael@0 1616 temp = ssl3_ConsumeHandshakeNumber(ss, 1, &buffer, &buffer_len);
michael@0 1617 if (temp < 0) goto no_ticket;
michael@0 1618 parsed_session_ticket->authAlgorithm = (SSLSignType)temp;
michael@0 1619 temp = ssl3_ConsumeHandshakeNumber(ss, 4, &buffer, &buffer_len);
michael@0 1620 if (temp < 0) goto no_ticket;
michael@0 1621 parsed_session_ticket->authKeyBits = (PRUint32)temp;
michael@0 1622 temp = ssl3_ConsumeHandshakeNumber(ss, 1, &buffer, &buffer_len);
michael@0 1623 if (temp < 0) goto no_ticket;
michael@0 1624 parsed_session_ticket->keaType = (SSLKEAType)temp;
michael@0 1625 temp = ssl3_ConsumeHandshakeNumber(ss, 4, &buffer, &buffer_len);
michael@0 1626 if (temp < 0) goto no_ticket;
michael@0 1627 parsed_session_ticket->keaKeyBits = (PRUint32)temp;
michael@0 1628
michael@0 1629 /* Read wrapped master_secret. */
michael@0 1630 temp = ssl3_ConsumeHandshakeNumber(ss, 1, &buffer, &buffer_len);
michael@0 1631 if (temp < 0) goto no_ticket;
michael@0 1632 parsed_session_ticket->ms_is_wrapped = (PRBool)temp;
michael@0 1633
michael@0 1634 temp = ssl3_ConsumeHandshakeNumber(ss, 1, &buffer, &buffer_len);
michael@0 1635 if (temp < 0) goto no_ticket;
michael@0 1636 parsed_session_ticket->exchKeyType = (SSL3KEAType)temp;
michael@0 1637
michael@0 1638 temp = ssl3_ConsumeHandshakeNumber(ss, 4, &buffer, &buffer_len);
michael@0 1639 if (temp < 0) goto no_ticket;
michael@0 1640 parsed_session_ticket->msWrapMech = (CK_MECHANISM_TYPE)temp;
michael@0 1641
michael@0 1642 temp = ssl3_ConsumeHandshakeNumber(ss, 2, &buffer, &buffer_len);
michael@0 1643 if (temp < 0) goto no_ticket;
michael@0 1644 parsed_session_ticket->ms_length = (PRUint16)temp;
michael@0 1645 if (parsed_session_ticket->ms_length == 0 || /* sanity check MS. */
michael@0 1646 parsed_session_ticket->ms_length >
michael@0 1647 sizeof(parsed_session_ticket->master_secret))
michael@0 1648 goto no_ticket;
michael@0 1649
michael@0 1650 /* Allow for the wrapped master secret to be longer. */
michael@0 1651 if (buffer_len < parsed_session_ticket->ms_length)
michael@0 1652 goto no_ticket;
michael@0 1653 PORT_Memcpy(parsed_session_ticket->master_secret, buffer,
michael@0 1654 parsed_session_ticket->ms_length);
michael@0 1655 buffer += parsed_session_ticket->ms_length;
michael@0 1656 buffer_len -= parsed_session_ticket->ms_length;
michael@0 1657
michael@0 1658 /* Read client_identity */
michael@0 1659 temp = ssl3_ConsumeHandshakeNumber(ss, 1, &buffer, &buffer_len);
michael@0 1660 if (temp < 0)
michael@0 1661 goto no_ticket;
michael@0 1662 parsed_session_ticket->client_identity.client_auth_type =
michael@0 1663 (ClientAuthenticationType)temp;
michael@0 1664 switch(parsed_session_ticket->client_identity.client_auth_type) {
michael@0 1665 case CLIENT_AUTH_ANONYMOUS:
michael@0 1666 break;
michael@0 1667 case CLIENT_AUTH_CERTIFICATE:
michael@0 1668 rv = ssl3_ConsumeHandshakeVariable(ss, &cert_item, 3,
michael@0 1669 &buffer, &buffer_len);
michael@0 1670 if (rv != SECSuccess) goto no_ticket;
michael@0 1671 rv = SECITEM_CopyItem(NULL, &parsed_session_ticket->peer_cert,
michael@0 1672 &cert_item);
michael@0 1673 if (rv != SECSuccess) goto no_ticket;
michael@0 1674 break;
michael@0 1675 default:
michael@0 1676 goto no_ticket;
michael@0 1677 }
michael@0 1678 /* Read timestamp. */
michael@0 1679 temp = ssl3_ConsumeHandshakeNumber(ss, 4, &buffer, &buffer_len);
michael@0 1680 if (temp < 0)
michael@0 1681 goto no_ticket;
michael@0 1682 parsed_session_ticket->timestamp = (PRUint32)temp;
michael@0 1683
michael@0 1684 /* Read server name */
michael@0 1685 nameType =
michael@0 1686 ssl3_ConsumeHandshakeNumber(ss, 1, &buffer, &buffer_len);
michael@0 1687 if (nameType != TLS_STE_NO_SERVER_NAME) {
michael@0 1688 SECItem name_item;
michael@0 1689 rv = ssl3_ConsumeHandshakeVariable(ss, &name_item, 2, &buffer,
michael@0 1690 &buffer_len);
michael@0 1691 if (rv != SECSuccess) goto no_ticket;
michael@0 1692 rv = SECITEM_CopyItem(NULL, &parsed_session_ticket->srvName,
michael@0 1693 &name_item);
michael@0 1694 if (rv != SECSuccess) goto no_ticket;
michael@0 1695 parsed_session_ticket->srvName.type = nameType;
michael@0 1696 }
michael@0 1697
michael@0 1698 /* Done parsing. Check that all bytes have been consumed. */
michael@0 1699 if (buffer_len != padding_length)
michael@0 1700 goto no_ticket;
michael@0 1701
michael@0 1702 /* Use the ticket if it has not expired, otherwise free the allocated
michael@0 1703 * memory since the ticket is of no use.
michael@0 1704 */
michael@0 1705 if (parsed_session_ticket->timestamp != 0 &&
michael@0 1706 parsed_session_ticket->timestamp +
michael@0 1707 TLS_EX_SESS_TICKET_LIFETIME_HINT > ssl_Time()) {
michael@0 1708
michael@0 1709 sid = ssl3_NewSessionID(ss, PR_TRUE);
michael@0 1710 if (sid == NULL) {
michael@0 1711 rv = SECFailure;
michael@0 1712 goto loser;
michael@0 1713 }
michael@0 1714
michael@0 1715 /* Copy over parameters. */
michael@0 1716 sid->version = parsed_session_ticket->ssl_version;
michael@0 1717 sid->u.ssl3.cipherSuite = parsed_session_ticket->cipher_suite;
michael@0 1718 sid->u.ssl3.compression = parsed_session_ticket->compression_method;
michael@0 1719 sid->authAlgorithm = parsed_session_ticket->authAlgorithm;
michael@0 1720 sid->authKeyBits = parsed_session_ticket->authKeyBits;
michael@0 1721 sid->keaType = parsed_session_ticket->keaType;
michael@0 1722 sid->keaKeyBits = parsed_session_ticket->keaKeyBits;
michael@0 1723
michael@0 1724 /* Copy master secret. */
michael@0 1725 #ifndef NO_PKCS11_BYPASS
michael@0 1726 if (ss->opt.bypassPKCS11 &&
michael@0 1727 parsed_session_ticket->ms_is_wrapped)
michael@0 1728 goto no_ticket;
michael@0 1729 #endif
michael@0 1730 if (parsed_session_ticket->ms_length >
michael@0 1731 sizeof(sid->u.ssl3.keys.wrapped_master_secret))
michael@0 1732 goto no_ticket;
michael@0 1733 PORT_Memcpy(sid->u.ssl3.keys.wrapped_master_secret,
michael@0 1734 parsed_session_ticket->master_secret,
michael@0 1735 parsed_session_ticket->ms_length);
michael@0 1736 sid->u.ssl3.keys.wrapped_master_secret_len =
michael@0 1737 parsed_session_ticket->ms_length;
michael@0 1738 sid->u.ssl3.exchKeyType = parsed_session_ticket->exchKeyType;
michael@0 1739 sid->u.ssl3.masterWrapMech = parsed_session_ticket->msWrapMech;
michael@0 1740 sid->u.ssl3.keys.msIsWrapped =
michael@0 1741 parsed_session_ticket->ms_is_wrapped;
michael@0 1742 sid->u.ssl3.masterValid = PR_TRUE;
michael@0 1743 sid->u.ssl3.keys.resumable = PR_TRUE;
michael@0 1744
michael@0 1745 /* Copy over client cert from session ticket if there is one. */
michael@0 1746 if (parsed_session_ticket->peer_cert.data != NULL) {
michael@0 1747 if (sid->peerCert != NULL)
michael@0 1748 CERT_DestroyCertificate(sid->peerCert);
michael@0 1749 sid->peerCert = CERT_NewTempCertificate(ss->dbHandle,
michael@0 1750 &parsed_session_ticket->peer_cert, NULL, PR_FALSE, PR_TRUE);
michael@0 1751 if (sid->peerCert == NULL) {
michael@0 1752 rv = SECFailure;
michael@0 1753 goto loser;
michael@0 1754 }
michael@0 1755 }
michael@0 1756 if (parsed_session_ticket->srvName.data != NULL) {
michael@0 1757 sid->u.ssl3.srvName = parsed_session_ticket->srvName;
michael@0 1758 }
michael@0 1759 ss->statelessResume = PR_TRUE;
michael@0 1760 ss->sec.ci.sid = sid;
michael@0 1761 }
michael@0 1762 }
michael@0 1763
michael@0 1764 if (0) {
michael@0 1765 no_ticket:
michael@0 1766 SSL_DBG(("%d: SSL[%d]: Session ticket parsing failed.",
michael@0 1767 SSL_GETPID(), ss->fd));
michael@0 1768 ssl3stats = SSL_GetStatistics();
michael@0 1769 SSL_AtomicIncrementLong(& ssl3stats->hch_sid_ticket_parse_failures );
michael@0 1770 }
michael@0 1771 rv = SECSuccess;
michael@0 1772
michael@0 1773 loser:
michael@0 1774 /* ss->sec.ci.sid == sid if it did NOT come here via goto statement
michael@0 1775 * in that case do not free sid
michael@0 1776 */
michael@0 1777 if (sid && (ss->sec.ci.sid != sid)) {
michael@0 1778 ssl_FreeSID(sid);
michael@0 1779 sid = NULL;
michael@0 1780 }
michael@0 1781 if (decrypted_state != NULL) {
michael@0 1782 SECITEM_FreeItem(decrypted_state, PR_TRUE);
michael@0 1783 decrypted_state = NULL;
michael@0 1784 }
michael@0 1785
michael@0 1786 if (parsed_session_ticket != NULL) {
michael@0 1787 if (parsed_session_ticket->peer_cert.data) {
michael@0 1788 SECITEM_FreeItem(&parsed_session_ticket->peer_cert, PR_FALSE);
michael@0 1789 }
michael@0 1790 PORT_ZFree(parsed_session_ticket, sizeof(SessionTicket));
michael@0 1791 }
michael@0 1792
michael@0 1793 return rv;
michael@0 1794 }
michael@0 1795
michael@0 1796 /*
michael@0 1797 * Read bytes. Using this function means the SECItem structure
michael@0 1798 * cannot be freed. The caller is expected to call this function
michael@0 1799 * on a shallow copy of the structure.
michael@0 1800 */
michael@0 1801 static SECStatus
michael@0 1802 ssl3_ConsumeFromItem(SECItem *item, unsigned char **buf, PRUint32 bytes)
michael@0 1803 {
michael@0 1804 if (bytes > item->len)
michael@0 1805 return SECFailure;
michael@0 1806
michael@0 1807 *buf = item->data;
michael@0 1808 item->data += bytes;
michael@0 1809 item->len -= bytes;
michael@0 1810 return SECSuccess;
michael@0 1811 }
michael@0 1812
michael@0 1813 static SECStatus
michael@0 1814 ssl3_ParseEncryptedSessionTicket(sslSocket *ss, SECItem *data,
michael@0 1815 EncryptedSessionTicket *enc_session_ticket)
michael@0 1816 {
michael@0 1817 if (ssl3_ConsumeFromItem(data, &enc_session_ticket->key_name,
michael@0 1818 SESS_TICKET_KEY_NAME_LEN) != SECSuccess)
michael@0 1819 return SECFailure;
michael@0 1820 if (ssl3_ConsumeFromItem(data, &enc_session_ticket->iv,
michael@0 1821 AES_BLOCK_SIZE) != SECSuccess)
michael@0 1822 return SECFailure;
michael@0 1823 if (ssl3_ConsumeHandshakeVariable(ss, &enc_session_ticket->encrypted_state,
michael@0 1824 2, &data->data, &data->len) != SECSuccess)
michael@0 1825 return SECFailure;
michael@0 1826 if (ssl3_ConsumeFromItem(data, &enc_session_ticket->mac,
michael@0 1827 TLS_EX_SESS_TICKET_MAC_LENGTH) != SECSuccess)
michael@0 1828 return SECFailure;
michael@0 1829 if (data->len != 0) /* Make sure that we have consumed all bytes. */
michael@0 1830 return SECFailure;
michael@0 1831
michael@0 1832 return SECSuccess;
michael@0 1833 }
michael@0 1834
michael@0 1835 /* go through hello extensions in buffer "b".
michael@0 1836 * For each one, find the extension handler in the table, and
michael@0 1837 * if present, invoke that handler.
michael@0 1838 * Servers ignore any extensions with unknown extension types.
michael@0 1839 * Clients reject any extensions with unadvertised extension types.
michael@0 1840 */
michael@0 1841 SECStatus
michael@0 1842 ssl3_HandleHelloExtensions(sslSocket *ss, SSL3Opaque **b, PRUint32 *length)
michael@0 1843 {
michael@0 1844 const ssl3HelloExtensionHandler * handlers;
michael@0 1845
michael@0 1846 if (ss->sec.isServer) {
michael@0 1847 handlers = clientHelloHandlers;
michael@0 1848 } else if (ss->version > SSL_LIBRARY_VERSION_3_0) {
michael@0 1849 handlers = serverHelloHandlersTLS;
michael@0 1850 } else {
michael@0 1851 handlers = serverHelloHandlersSSL3;
michael@0 1852 }
michael@0 1853
michael@0 1854 while (*length) {
michael@0 1855 const ssl3HelloExtensionHandler * handler;
michael@0 1856 SECStatus rv;
michael@0 1857 PRInt32 extension_type;
michael@0 1858 SECItem extension_data;
michael@0 1859
michael@0 1860 /* Get the extension's type field */
michael@0 1861 extension_type = ssl3_ConsumeHandshakeNumber(ss, 2, b, length);
michael@0 1862 if (extension_type < 0) /* failure to decode extension_type */
michael@0 1863 return SECFailure; /* alert already sent */
michael@0 1864
michael@0 1865 /* get the data for this extension, so we can pass it or skip it. */
michael@0 1866 rv = ssl3_ConsumeHandshakeVariable(ss, &extension_data, 2, b, length);
michael@0 1867 if (rv != SECSuccess)
michael@0 1868 return rv;
michael@0 1869
michael@0 1870 /* Check whether the server sent an extension which was not advertised
michael@0 1871 * in the ClientHello.
michael@0 1872 */
michael@0 1873 if (!ss->sec.isServer &&
michael@0 1874 !ssl3_ClientExtensionAdvertised(ss, extension_type))
michael@0 1875 return SECFailure; /* TODO: send unsupported_extension alert */
michael@0 1876
michael@0 1877 /* Check whether an extension has been sent multiple times. */
michael@0 1878 if (ssl3_ExtensionNegotiated(ss, extension_type))
michael@0 1879 return SECFailure;
michael@0 1880
michael@0 1881 /* find extension_type in table of Hello Extension Handlers */
michael@0 1882 for (handler = handlers; handler->ex_type >= 0; handler++) {
michael@0 1883 /* if found, call this handler */
michael@0 1884 if (handler->ex_type == extension_type) {
michael@0 1885 rv = (*handler->ex_handler)(ss, (PRUint16)extension_type,
michael@0 1886 &extension_data);
michael@0 1887 /* Ignore this result */
michael@0 1888 /* Treat all bad extensions as unrecognized types. */
michael@0 1889 break;
michael@0 1890 }
michael@0 1891 }
michael@0 1892 }
michael@0 1893 return SECSuccess;
michael@0 1894 }
michael@0 1895
michael@0 1896 /* Add a callback function to the table of senders of server hello extensions.
michael@0 1897 */
michael@0 1898 SECStatus
michael@0 1899 ssl3_RegisterServerHelloExtensionSender(sslSocket *ss, PRUint16 ex_type,
michael@0 1900 ssl3HelloExtensionSenderFunc cb)
michael@0 1901 {
michael@0 1902 int i;
michael@0 1903 ssl3HelloExtensionSender *sender = &ss->xtnData.serverSenders[0];
michael@0 1904
michael@0 1905 for (i = 0; i < SSL_MAX_EXTENSIONS; ++i, ++sender) {
michael@0 1906 if (!sender->ex_sender) {
michael@0 1907 sender->ex_type = ex_type;
michael@0 1908 sender->ex_sender = cb;
michael@0 1909 return SECSuccess;
michael@0 1910 }
michael@0 1911 /* detect duplicate senders */
michael@0 1912 PORT_Assert(sender->ex_type != ex_type);
michael@0 1913 if (sender->ex_type == ex_type) {
michael@0 1914 /* duplicate */
michael@0 1915 break;
michael@0 1916 }
michael@0 1917 }
michael@0 1918 PORT_Assert(i < SSL_MAX_EXTENSIONS); /* table needs to grow */
michael@0 1919 PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
michael@0 1920 return SECFailure;
michael@0 1921 }
michael@0 1922
michael@0 1923 /* call each of the extension senders and return the accumulated length */
michael@0 1924 PRInt32
michael@0 1925 ssl3_CallHelloExtensionSenders(sslSocket *ss, PRBool append, PRUint32 maxBytes,
michael@0 1926 const ssl3HelloExtensionSender *sender)
michael@0 1927 {
michael@0 1928 PRInt32 total_exten_len = 0;
michael@0 1929 int i;
michael@0 1930
michael@0 1931 if (!sender) {
michael@0 1932 sender = ss->version > SSL_LIBRARY_VERSION_3_0 ?
michael@0 1933 &clientHelloSendersTLS[0] : &clientHelloSendersSSL3[0];
michael@0 1934 }
michael@0 1935
michael@0 1936 for (i = 0; i < SSL_MAX_EXTENSIONS; ++i, ++sender) {
michael@0 1937 if (sender->ex_sender) {
michael@0 1938 PRInt32 extLen = (*sender->ex_sender)(ss, append, maxBytes);
michael@0 1939 if (extLen < 0)
michael@0 1940 return -1;
michael@0 1941 maxBytes -= extLen;
michael@0 1942 total_exten_len += extLen;
michael@0 1943 }
michael@0 1944 }
michael@0 1945 return total_exten_len;
michael@0 1946 }
michael@0 1947
michael@0 1948
michael@0 1949 /* Extension format:
michael@0 1950 * Extension number: 2 bytes
michael@0 1951 * Extension length: 2 bytes
michael@0 1952 * Verify Data Length: 1 byte
michael@0 1953 * Verify Data (TLS): 12 bytes (client) or 24 bytes (server)
michael@0 1954 * Verify Data (SSL): 36 bytes (client) or 72 bytes (server)
michael@0 1955 */
michael@0 1956 static PRInt32
michael@0 1957 ssl3_SendRenegotiationInfoXtn(
michael@0 1958 sslSocket * ss,
michael@0 1959 PRBool append,
michael@0 1960 PRUint32 maxBytes)
michael@0 1961 {
michael@0 1962 PRInt32 len, needed;
michael@0 1963
michael@0 1964 /* In draft-ietf-tls-renegotiation-03, it is NOT RECOMMENDED to send
michael@0 1965 * both the SCSV and the empty RI, so when we send SCSV in
michael@0 1966 * the initial handshake, we don't also send RI.
michael@0 1967 */
michael@0 1968 if (!ss || ss->ssl3.hs.sendingSCSV)
michael@0 1969 return 0;
michael@0 1970 len = !ss->firstHsDone ? 0 :
michael@0 1971 (ss->sec.isServer ? ss->ssl3.hs.finishedBytes * 2
michael@0 1972 : ss->ssl3.hs.finishedBytes);
michael@0 1973 needed = 5 + len;
michael@0 1974 if (append && maxBytes >= needed) {
michael@0 1975 SECStatus rv;
michael@0 1976 /* extension_type */
michael@0 1977 rv = ssl3_AppendHandshakeNumber(ss, ssl_renegotiation_info_xtn, 2);
michael@0 1978 if (rv != SECSuccess) return -1;
michael@0 1979 /* length of extension_data */
michael@0 1980 rv = ssl3_AppendHandshakeNumber(ss, len + 1, 2);
michael@0 1981 if (rv != SECSuccess) return -1;
michael@0 1982 /* verify_Data from previous Finished message(s) */
michael@0 1983 rv = ssl3_AppendHandshakeVariable(ss,
michael@0 1984 ss->ssl3.hs.finishedMsgs.data, len, 1);
michael@0 1985 if (rv != SECSuccess) return -1;
michael@0 1986 if (!ss->sec.isServer) {
michael@0 1987 TLSExtensionData *xtnData = &ss->xtnData;
michael@0 1988 xtnData->advertised[xtnData->numAdvertised++] =
michael@0 1989 ssl_renegotiation_info_xtn;
michael@0 1990 }
michael@0 1991 }
michael@0 1992 return needed;
michael@0 1993 }
michael@0 1994
michael@0 1995 static SECStatus
michael@0 1996 ssl3_ServerHandleStatusRequestXtn(sslSocket *ss, PRUint16 ex_type,
michael@0 1997 SECItem *data)
michael@0 1998 {
michael@0 1999 SECStatus rv = SECSuccess;
michael@0 2000
michael@0 2001 /* remember that we got this extension. */
michael@0 2002 ss->xtnData.negotiated[ss->xtnData.numNegotiated++] = ex_type;
michael@0 2003 PORT_Assert(ss->sec.isServer);
michael@0 2004 /* prepare to send back the appropriate response */
michael@0 2005 rv = ssl3_RegisterServerHelloExtensionSender(ss, ex_type,
michael@0 2006 ssl3_ServerSendStatusRequestXtn);
michael@0 2007 return rv;
michael@0 2008 }
michael@0 2009
michael@0 2010 /* This function runs in both the client and server. */
michael@0 2011 static SECStatus
michael@0 2012 ssl3_HandleRenegotiationInfoXtn(sslSocket *ss, PRUint16 ex_type, SECItem *data)
michael@0 2013 {
michael@0 2014 SECStatus rv = SECSuccess;
michael@0 2015 PRUint32 len = 0;
michael@0 2016
michael@0 2017 if (ss->firstHsDone) {
michael@0 2018 len = ss->sec.isServer ? ss->ssl3.hs.finishedBytes
michael@0 2019 : ss->ssl3.hs.finishedBytes * 2;
michael@0 2020 }
michael@0 2021 if (data->len != 1 + len ||
michael@0 2022 data->data[0] != len || (len &&
michael@0 2023 NSS_SecureMemcmp(ss->ssl3.hs.finishedMsgs.data,
michael@0 2024 data->data + 1, len))) {
michael@0 2025 /* Can we do this here? Or, must we arrange for the caller to do it? */
michael@0 2026 (void)SSL3_SendAlert(ss, alert_fatal, handshake_failure);
michael@0 2027 PORT_SetError(SSL_ERROR_BAD_HANDSHAKE_HASH_VALUE);
michael@0 2028 return SECFailure;
michael@0 2029 }
michael@0 2030 /* remember that we got this extension and it was correct. */
michael@0 2031 ss->peerRequestedProtection = 1;
michael@0 2032 ss->xtnData.negotiated[ss->xtnData.numNegotiated++] = ex_type;
michael@0 2033 if (ss->sec.isServer) {
michael@0 2034 /* prepare to send back the appropriate response */
michael@0 2035 rv = ssl3_RegisterServerHelloExtensionSender(ss, ex_type,
michael@0 2036 ssl3_SendRenegotiationInfoXtn);
michael@0 2037 }
michael@0 2038 return rv;
michael@0 2039 }
michael@0 2040
michael@0 2041 static PRInt32
michael@0 2042 ssl3_SendUseSRTPXtn(sslSocket *ss, PRBool append, PRUint32 maxBytes)
michael@0 2043 {
michael@0 2044 PRUint32 ext_data_len;
michael@0 2045 PRInt16 i;
michael@0 2046 SECStatus rv;
michael@0 2047
michael@0 2048 if (!ss)
michael@0 2049 return 0;
michael@0 2050
michael@0 2051 if (!ss->sec.isServer) {
michael@0 2052 /* Client side */
michael@0 2053
michael@0 2054 if (!IS_DTLS(ss) || !ss->ssl3.dtlsSRTPCipherCount)
michael@0 2055 return 0; /* Not relevant */
michael@0 2056
michael@0 2057 ext_data_len = 2 + 2 * ss->ssl3.dtlsSRTPCipherCount + 1;
michael@0 2058
michael@0 2059 if (append && maxBytes >= 4 + ext_data_len) {
michael@0 2060 /* Extension type */
michael@0 2061 rv = ssl3_AppendHandshakeNumber(ss, ssl_use_srtp_xtn, 2);
michael@0 2062 if (rv != SECSuccess) return -1;
michael@0 2063 /* Length of extension data */
michael@0 2064 rv = ssl3_AppendHandshakeNumber(ss, ext_data_len, 2);
michael@0 2065 if (rv != SECSuccess) return -1;
michael@0 2066 /* Length of the SRTP cipher list */
michael@0 2067 rv = ssl3_AppendHandshakeNumber(ss,
michael@0 2068 2 * ss->ssl3.dtlsSRTPCipherCount,
michael@0 2069 2);
michael@0 2070 if (rv != SECSuccess) return -1;
michael@0 2071 /* The SRTP ciphers */
michael@0 2072 for (i = 0; i < ss->ssl3.dtlsSRTPCipherCount; i++) {
michael@0 2073 rv = ssl3_AppendHandshakeNumber(ss,
michael@0 2074 ss->ssl3.dtlsSRTPCiphers[i],
michael@0 2075 2);
michael@0 2076 }
michael@0 2077 /* Empty MKI value */
michael@0 2078 ssl3_AppendHandshakeVariable(ss, NULL, 0, 1);
michael@0 2079
michael@0 2080 ss->xtnData.advertised[ss->xtnData.numAdvertised++] =
michael@0 2081 ssl_use_srtp_xtn;
michael@0 2082 }
michael@0 2083
michael@0 2084 return 4 + ext_data_len;
michael@0 2085 }
michael@0 2086
michael@0 2087 /* Server side */
michael@0 2088 if (append && maxBytes >= 9) {
michael@0 2089 /* Extension type */
michael@0 2090 rv = ssl3_AppendHandshakeNumber(ss, ssl_use_srtp_xtn, 2);
michael@0 2091 if (rv != SECSuccess) return -1;
michael@0 2092 /* Length of extension data */
michael@0 2093 rv = ssl3_AppendHandshakeNumber(ss, 5, 2);
michael@0 2094 if (rv != SECSuccess) return -1;
michael@0 2095 /* Length of the SRTP cipher list */
michael@0 2096 rv = ssl3_AppendHandshakeNumber(ss, 2, 2);
michael@0 2097 if (rv != SECSuccess) return -1;
michael@0 2098 /* The selected cipher */
michael@0 2099 rv = ssl3_AppendHandshakeNumber(ss, ss->ssl3.dtlsSRTPCipherSuite, 2);
michael@0 2100 if (rv != SECSuccess) return -1;
michael@0 2101 /* Empty MKI value */
michael@0 2102 ssl3_AppendHandshakeVariable(ss, NULL, 0, 1);
michael@0 2103 }
michael@0 2104
michael@0 2105 return 9;
michael@0 2106 }
michael@0 2107
michael@0 2108 static SECStatus
michael@0 2109 ssl3_HandleUseSRTPXtn(sslSocket * ss, PRUint16 ex_type, SECItem *data)
michael@0 2110 {
michael@0 2111 SECStatus rv;
michael@0 2112 SECItem ciphers = {siBuffer, NULL, 0};
michael@0 2113 PRUint16 i;
michael@0 2114 unsigned int j;
michael@0 2115 PRUint16 cipher = 0;
michael@0 2116 PRBool found = PR_FALSE;
michael@0 2117 SECItem litem;
michael@0 2118
michael@0 2119 if (!ss->sec.isServer) {
michael@0 2120 /* Client side */
michael@0 2121 if (!data->data || !data->len) {
michael@0 2122 /* malformed */
michael@0 2123 return SECFailure;
michael@0 2124 }
michael@0 2125
michael@0 2126 /* Get the cipher list */
michael@0 2127 rv = ssl3_ConsumeHandshakeVariable(ss, &ciphers, 2,
michael@0 2128 &data->data, &data->len);
michael@0 2129 if (rv != SECSuccess) {
michael@0 2130 return SECFailure;
michael@0 2131 }
michael@0 2132 /* Now check that the number of ciphers listed is 1 (len = 2) */
michael@0 2133 if (ciphers.len != 2) {
michael@0 2134 return SECFailure;
michael@0 2135 }
michael@0 2136
michael@0 2137 /* Get the selected cipher */
michael@0 2138 cipher = (ciphers.data[0] << 8) | ciphers.data[1];
michael@0 2139
michael@0 2140 /* Now check that this is one of the ciphers we offered */
michael@0 2141 for (i = 0; i < ss->ssl3.dtlsSRTPCipherCount; i++) {
michael@0 2142 if (cipher == ss->ssl3.dtlsSRTPCiphers[i]) {
michael@0 2143 found = PR_TRUE;
michael@0 2144 break;
michael@0 2145 }
michael@0 2146 }
michael@0 2147
michael@0 2148 if (!found) {
michael@0 2149 return SECFailure;
michael@0 2150 }
michael@0 2151
michael@0 2152 /* Get the srtp_mki value */
michael@0 2153 rv = ssl3_ConsumeHandshakeVariable(ss, &litem, 1,
michael@0 2154 &data->data, &data->len);
michael@0 2155 if (rv != SECSuccess) {
michael@0 2156 return SECFailure;
michael@0 2157 }
michael@0 2158
michael@0 2159 /* We didn't offer an MKI, so this must be 0 length */
michael@0 2160 /* XXX RFC 5764 Section 4.1.3 says:
michael@0 2161 * If the client detects a nonzero-length MKI in the server's
michael@0 2162 * response that is different than the one the client offered,
michael@0 2163 * then the client MUST abort the handshake and SHOULD send an
michael@0 2164 * invalid_parameter alert.
michael@0 2165 *
michael@0 2166 * Due to a limitation of the ssl3_HandleHelloExtensions function,
michael@0 2167 * returning SECFailure here won't abort the handshake. It will
michael@0 2168 * merely cause the use_srtp extension to be not negotiated. We
michael@0 2169 * should fix this. See NSS bug 753136.
michael@0 2170 */
michael@0 2171 if (litem.len != 0) {
michael@0 2172 return SECFailure;
michael@0 2173 }
michael@0 2174
michael@0 2175 if (data->len != 0) {
michael@0 2176 /* malformed */
michael@0 2177 return SECFailure;
michael@0 2178 }
michael@0 2179
michael@0 2180 /* OK, this looks fine. */
michael@0 2181 ss->xtnData.negotiated[ss->xtnData.numNegotiated++] = ssl_use_srtp_xtn;
michael@0 2182 ss->ssl3.dtlsSRTPCipherSuite = cipher;
michael@0 2183 return SECSuccess;
michael@0 2184 }
michael@0 2185
michael@0 2186 /* Server side */
michael@0 2187 if (!IS_DTLS(ss) || !ss->ssl3.dtlsSRTPCipherCount) {
michael@0 2188 /* Ignore the extension if we aren't doing DTLS or no DTLS-SRTP
michael@0 2189 * preferences have been set. */
michael@0 2190 return SECSuccess;
michael@0 2191 }
michael@0 2192
michael@0 2193 if (!data->data || data->len < 5) {
michael@0 2194 /* malformed */
michael@0 2195 return SECFailure;
michael@0 2196 }
michael@0 2197
michael@0 2198 /* Get the cipher list */
michael@0 2199 rv = ssl3_ConsumeHandshakeVariable(ss, &ciphers, 2,
michael@0 2200 &data->data, &data->len);
michael@0 2201 if (rv != SECSuccess) {
michael@0 2202 return SECFailure;
michael@0 2203 }
michael@0 2204 /* Check that the list is even length */
michael@0 2205 if (ciphers.len % 2) {
michael@0 2206 return SECFailure;
michael@0 2207 }
michael@0 2208
michael@0 2209 /* Walk through the offered list and pick the most preferred of our
michael@0 2210 * ciphers, if any */
michael@0 2211 for (i = 0; !found && i < ss->ssl3.dtlsSRTPCipherCount; i++) {
michael@0 2212 for (j = 0; j + 1 < ciphers.len; j += 2) {
michael@0 2213 cipher = (ciphers.data[j] << 8) | ciphers.data[j + 1];
michael@0 2214 if (cipher == ss->ssl3.dtlsSRTPCiphers[i]) {
michael@0 2215 found = PR_TRUE;
michael@0 2216 break;
michael@0 2217 }
michael@0 2218 }
michael@0 2219 }
michael@0 2220
michael@0 2221 /* Get the srtp_mki value */
michael@0 2222 rv = ssl3_ConsumeHandshakeVariable(ss, &litem, 1, &data->data, &data->len);
michael@0 2223 if (rv != SECSuccess) {
michael@0 2224 return SECFailure;
michael@0 2225 }
michael@0 2226
michael@0 2227 if (data->len != 0) {
michael@0 2228 return SECFailure; /* Malformed */
michael@0 2229 }
michael@0 2230
michael@0 2231 /* Now figure out what to do */
michael@0 2232 if (!found) {
michael@0 2233 /* No matching ciphers */
michael@0 2234 return SECSuccess;
michael@0 2235 }
michael@0 2236
michael@0 2237 /* OK, we have a valid cipher and we've selected it */
michael@0 2238 ss->ssl3.dtlsSRTPCipherSuite = cipher;
michael@0 2239 ss->xtnData.negotiated[ss->xtnData.numNegotiated++] = ssl_use_srtp_xtn;
michael@0 2240
michael@0 2241 return ssl3_RegisterServerHelloExtensionSender(ss, ssl_use_srtp_xtn,
michael@0 2242 ssl3_SendUseSRTPXtn);
michael@0 2243 }
michael@0 2244
michael@0 2245 /* ssl3_ServerHandleSigAlgsXtn handles the signature_algorithms extension
michael@0 2246 * from a client.
michael@0 2247 * See https://tools.ietf.org/html/rfc5246#section-7.4.1.4.1 */
michael@0 2248 static SECStatus
michael@0 2249 ssl3_ServerHandleSigAlgsXtn(sslSocket * ss, PRUint16 ex_type, SECItem *data)
michael@0 2250 {
michael@0 2251 SECStatus rv;
michael@0 2252 SECItem algorithms;
michael@0 2253 const unsigned char *b;
michael@0 2254 unsigned int numAlgorithms, i;
michael@0 2255
michael@0 2256 /* Ignore this extension if we aren't doing TLS 1.2 or greater. */
michael@0 2257 if (ss->version < SSL_LIBRARY_VERSION_TLS_1_2) {
michael@0 2258 return SECSuccess;
michael@0 2259 }
michael@0 2260
michael@0 2261 /* Keep track of negotiated extensions. */
michael@0 2262 ss->xtnData.negotiated[ss->xtnData.numNegotiated++] = ex_type;
michael@0 2263
michael@0 2264 rv = ssl3_ConsumeHandshakeVariable(ss, &algorithms, 2, &data->data,
michael@0 2265 &data->len);
michael@0 2266 if (rv != SECSuccess) {
michael@0 2267 return SECFailure;
michael@0 2268 }
michael@0 2269 /* Trailing data, empty value, or odd-length value is invalid. */
michael@0 2270 if (data->len != 0 || algorithms.len == 0 || (algorithms.len & 1) != 0) {
michael@0 2271 PORT_SetError(SSL_ERROR_RX_MALFORMED_CLIENT_HELLO);
michael@0 2272 return SECFailure;
michael@0 2273 }
michael@0 2274
michael@0 2275 numAlgorithms = algorithms.len/2;
michael@0 2276
michael@0 2277 /* We don't care to process excessive numbers of algorithms. */
michael@0 2278 if (numAlgorithms > 512) {
michael@0 2279 numAlgorithms = 512;
michael@0 2280 }
michael@0 2281
michael@0 2282 ss->ssl3.hs.clientSigAndHash =
michael@0 2283 PORT_NewArray(SSL3SignatureAndHashAlgorithm, numAlgorithms);
michael@0 2284 if (!ss->ssl3.hs.clientSigAndHash) {
michael@0 2285 return SECFailure;
michael@0 2286 }
michael@0 2287 ss->ssl3.hs.numClientSigAndHash = 0;
michael@0 2288
michael@0 2289 b = algorithms.data;
michael@0 2290 for (i = 0; i < numAlgorithms; i++) {
michael@0 2291 unsigned char tls_hash = *(b++);
michael@0 2292 unsigned char tls_sig = *(b++);
michael@0 2293 SECOidTag hash = ssl3_TLSHashAlgorithmToOID(tls_hash);
michael@0 2294
michael@0 2295 if (hash == SEC_OID_UNKNOWN) {
michael@0 2296 /* We ignore formats that we don't understand. */
michael@0 2297 continue;
michael@0 2298 }
michael@0 2299 /* tls_sig support will be checked later in
michael@0 2300 * ssl3_PickSignatureHashAlgorithm. */
michael@0 2301 ss->ssl3.hs.clientSigAndHash[i].hashAlg = hash;
michael@0 2302 ss->ssl3.hs.clientSigAndHash[i].sigAlg = tls_sig;
michael@0 2303 ss->ssl3.hs.numClientSigAndHash++;
michael@0 2304 }
michael@0 2305
michael@0 2306 if (!ss->ssl3.hs.numClientSigAndHash) {
michael@0 2307 /* We didn't understand any of the client's requested signature
michael@0 2308 * formats. We'll use the defaults. */
michael@0 2309 PORT_Free(ss->ssl3.hs.clientSigAndHash);
michael@0 2310 ss->ssl3.hs.clientSigAndHash = NULL;
michael@0 2311 }
michael@0 2312
michael@0 2313 return SECSuccess;
michael@0 2314 }
michael@0 2315
michael@0 2316 /* ssl3_ClientSendSigAlgsXtn sends the signature_algorithm extension for TLS
michael@0 2317 * 1.2 ClientHellos. */
michael@0 2318 static PRInt32
michael@0 2319 ssl3_ClientSendSigAlgsXtn(sslSocket * ss, PRBool append, PRUint32 maxBytes)
michael@0 2320 {
michael@0 2321 static const unsigned char signatureAlgorithms[] = {
michael@0 2322 /* This block is the contents of our signature_algorithms extension, in
michael@0 2323 * wire format. See
michael@0 2324 * https://tools.ietf.org/html/rfc5246#section-7.4.1.4.1 */
michael@0 2325 tls_hash_sha256, tls_sig_rsa,
michael@0 2326 tls_hash_sha384, tls_sig_rsa,
michael@0 2327 tls_hash_sha1, tls_sig_rsa,
michael@0 2328 #ifndef NSS_DISABLE_ECC
michael@0 2329 tls_hash_sha256, tls_sig_ecdsa,
michael@0 2330 tls_hash_sha384, tls_sig_ecdsa,
michael@0 2331 tls_hash_sha1, tls_sig_ecdsa,
michael@0 2332 #endif
michael@0 2333 tls_hash_sha256, tls_sig_dsa,
michael@0 2334 tls_hash_sha1, tls_sig_dsa,
michael@0 2335 };
michael@0 2336 PRInt32 extension_length;
michael@0 2337
michael@0 2338 if (ss->version < SSL_LIBRARY_VERSION_TLS_1_2) {
michael@0 2339 return 0;
michael@0 2340 }
michael@0 2341
michael@0 2342 extension_length =
michael@0 2343 2 /* extension type */ +
michael@0 2344 2 /* extension length */ +
michael@0 2345 2 /* supported_signature_algorithms length */ +
michael@0 2346 sizeof(signatureAlgorithms);
michael@0 2347
michael@0 2348 if (append && maxBytes >= extension_length) {
michael@0 2349 SECStatus rv;
michael@0 2350 rv = ssl3_AppendHandshakeNumber(ss, ssl_signature_algorithms_xtn, 2);
michael@0 2351 if (rv != SECSuccess)
michael@0 2352 goto loser;
michael@0 2353 rv = ssl3_AppendHandshakeNumber(ss, extension_length - 4, 2);
michael@0 2354 if (rv != SECSuccess)
michael@0 2355 goto loser;
michael@0 2356 rv = ssl3_AppendHandshakeVariable(ss, signatureAlgorithms,
michael@0 2357 sizeof(signatureAlgorithms), 2);
michael@0 2358 if (rv != SECSuccess)
michael@0 2359 goto loser;
michael@0 2360 ss->xtnData.advertised[ss->xtnData.numAdvertised++] =
michael@0 2361 ssl_signature_algorithms_xtn;
michael@0 2362 } else if (maxBytes < extension_length) {
michael@0 2363 PORT_Assert(0);
michael@0 2364 return 0;
michael@0 2365 }
michael@0 2366
michael@0 2367 return extension_length;
michael@0 2368
michael@0 2369 loser:
michael@0 2370 return -1;
michael@0 2371 }
michael@0 2372
michael@0 2373 unsigned int
michael@0 2374 ssl3_CalculatePaddingExtensionLength(unsigned int clientHelloLength)
michael@0 2375 {
michael@0 2376 unsigned int recordLength = 1 /* handshake message type */ +
michael@0 2377 3 /* handshake message length */ +
michael@0 2378 clientHelloLength;
michael@0 2379 unsigned int extensionLength;
michael@0 2380
michael@0 2381 if (recordLength < 256 || recordLength >= 512) {
michael@0 2382 return 0;
michael@0 2383 }
michael@0 2384
michael@0 2385 extensionLength = 512 - recordLength;
michael@0 2386 /* Extensions take at least four bytes to encode. */
michael@0 2387 if (extensionLength < 4) {
michael@0 2388 extensionLength = 4;
michael@0 2389 }
michael@0 2390
michael@0 2391 return extensionLength;
michael@0 2392 }
michael@0 2393
michael@0 2394 /* ssl3_AppendPaddingExtension possibly adds an extension which ensures that a
michael@0 2395 * ClientHello record is either < 256 bytes or is >= 512 bytes. This ensures
michael@0 2396 * that we don't trigger bugs in F5 products. */
michael@0 2397 PRInt32
michael@0 2398 ssl3_AppendPaddingExtension(sslSocket *ss, unsigned int extensionLen,
michael@0 2399 PRUint32 maxBytes)
michael@0 2400 {
michael@0 2401 unsigned int paddingLen = extensionLen - 4;
michael@0 2402 static unsigned char padding[256];
michael@0 2403
michael@0 2404 if (extensionLen == 0) {
michael@0 2405 return 0;
michael@0 2406 }
michael@0 2407
michael@0 2408 if (extensionLen < 4 ||
michael@0 2409 extensionLen > maxBytes ||
michael@0 2410 paddingLen > sizeof(padding)) {
michael@0 2411 PORT_Assert(0);
michael@0 2412 return -1;
michael@0 2413 }
michael@0 2414
michael@0 2415 if (SECSuccess != ssl3_AppendHandshakeNumber(ss, ssl_padding_xtn, 2))
michael@0 2416 return -1;
michael@0 2417 if (SECSuccess != ssl3_AppendHandshakeNumber(ss, paddingLen, 2))
michael@0 2418 return -1;
michael@0 2419 if (SECSuccess != ssl3_AppendHandshake(ss, padding, paddingLen))
michael@0 2420 return -1;
michael@0 2421
michael@0 2422 return extensionLen;
michael@0 2423 }

mercurial