security/nss/lib/ssl/ssl3ext.c

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/security/nss/lib/ssl/ssl3ext.c	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,2423 @@
     1.4 +/*
     1.5 + * SSL3 Protocol
     1.6 + *
     1.7 + * This Source Code Form is subject to the terms of the Mozilla Public
     1.8 + * License, v. 2.0. If a copy of the MPL was not distributed with this
     1.9 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
    1.10 +
    1.11 +/* TLS extension code moved here from ssl3ecc.c */
    1.12 +
    1.13 +#include "nssrenam.h"
    1.14 +#include "nss.h"
    1.15 +#include "ssl.h"
    1.16 +#include "sslproto.h"
    1.17 +#include "sslimpl.h"
    1.18 +#include "pk11pub.h"
    1.19 +#ifdef NO_PKCS11_BYPASS
    1.20 +#include "blapit.h"
    1.21 +#else
    1.22 +#include "blapi.h"
    1.23 +#endif
    1.24 +#include "prinit.h"
    1.25 +
    1.26 +static unsigned char  key_name[SESS_TICKET_KEY_NAME_LEN];
    1.27 +static PK11SymKey    *session_ticket_enc_key_pkcs11 = NULL;
    1.28 +static PK11SymKey    *session_ticket_mac_key_pkcs11 = NULL;
    1.29 +
    1.30 +#ifndef NO_PKCS11_BYPASS
    1.31 +static unsigned char  session_ticket_enc_key[AES_256_KEY_LENGTH];
    1.32 +static unsigned char  session_ticket_mac_key[SHA256_LENGTH];
    1.33 +
    1.34 +static PRBool         session_ticket_keys_initialized = PR_FALSE;
    1.35 +#endif
    1.36 +static PRCallOnceType generate_session_keys_once;
    1.37 +
    1.38 +/* forward static function declarations */
    1.39 +static SECStatus ssl3_ParseEncryptedSessionTicket(sslSocket *ss,
    1.40 +    SECItem *data, EncryptedSessionTicket *enc_session_ticket);
    1.41 +static SECStatus ssl3_AppendToItem(SECItem *item, const unsigned char *buf,
    1.42 +    PRUint32 bytes);
    1.43 +static SECStatus ssl3_AppendNumberToItem(SECItem *item, PRUint32 num,
    1.44 +    PRInt32 lenSize);
    1.45 +static SECStatus ssl3_GetSessionTicketKeysPKCS11(sslSocket *ss,
    1.46 +    PK11SymKey **aes_key, PK11SymKey **mac_key);
    1.47 +#ifndef NO_PKCS11_BYPASS
    1.48 +static SECStatus ssl3_GetSessionTicketKeys(const unsigned char **aes_key,
    1.49 +    PRUint32 *aes_key_length, const unsigned char **mac_key,
    1.50 +    PRUint32 *mac_key_length);
    1.51 +#endif
    1.52 +static PRInt32 ssl3_SendRenegotiationInfoXtn(sslSocket * ss,
    1.53 +    PRBool append, PRUint32 maxBytes);
    1.54 +static SECStatus ssl3_HandleRenegotiationInfoXtn(sslSocket *ss,
    1.55 +    PRUint16 ex_type, SECItem *data);
    1.56 +static SECStatus ssl3_ClientHandleNextProtoNegoXtn(sslSocket *ss,
    1.57 +                        PRUint16 ex_type, SECItem *data);
    1.58 +static SECStatus ssl3_ClientHandleAppProtoXtn(sslSocket *ss,
    1.59 +                        PRUint16 ex_type, SECItem *data);
    1.60 +static SECStatus ssl3_ServerHandleNextProtoNegoXtn(sslSocket *ss,
    1.61 +                        PRUint16 ex_type, SECItem *data);
    1.62 +static SECStatus ssl3_ServerHandleAppProtoXtn(sslSocket *ss, PRUint16 ex_type,
    1.63 +                                              SECItem *data);
    1.64 +static PRInt32 ssl3_ClientSendNextProtoNegoXtn(sslSocket *ss, PRBool append,
    1.65 +                                               PRUint32 maxBytes);
    1.66 +static PRInt32 ssl3_ClientSendAppProtoXtn(sslSocket *ss, PRBool append,
    1.67 +                                          PRUint32 maxBytes);
    1.68 +static PRInt32 ssl3_ServerSendAppProtoXtn(sslSocket *ss, PRBool append,
    1.69 +                                          PRUint32 maxBytes);
    1.70 +static PRInt32 ssl3_SendUseSRTPXtn(sslSocket *ss, PRBool append,
    1.71 +    PRUint32 maxBytes);
    1.72 +static SECStatus ssl3_HandleUseSRTPXtn(sslSocket * ss, PRUint16 ex_type,
    1.73 +    SECItem *data);
    1.74 +static PRInt32 ssl3_ServerSendStatusRequestXtn(sslSocket * ss,
    1.75 +    PRBool append, PRUint32 maxBytes);
    1.76 +static SECStatus ssl3_ServerHandleStatusRequestXtn(sslSocket *ss,
    1.77 +    PRUint16 ex_type, SECItem *data);
    1.78 +static SECStatus ssl3_ClientHandleStatusRequestXtn(sslSocket *ss,
    1.79 +                                                   PRUint16 ex_type,
    1.80 +                                                   SECItem *data);
    1.81 +static PRInt32 ssl3_ClientSendStatusRequestXtn(sslSocket * ss, PRBool append,
    1.82 +                                               PRUint32 maxBytes);
    1.83 +static PRInt32 ssl3_ClientSendSigAlgsXtn(sslSocket *ss, PRBool append,
    1.84 +                                         PRUint32 maxBytes);
    1.85 +static SECStatus ssl3_ServerHandleSigAlgsXtn(sslSocket *ss, PRUint16 ex_type,
    1.86 +                                             SECItem *data);
    1.87 +
    1.88 +/*
    1.89 + * Write bytes.  Using this function means the SECItem structure
    1.90 + * cannot be freed.  The caller is expected to call this function
    1.91 + * on a shallow copy of the structure.
    1.92 + */
    1.93 +static SECStatus
    1.94 +ssl3_AppendToItem(SECItem *item, const unsigned char *buf, PRUint32 bytes)
    1.95 +{
    1.96 +    if (bytes > item->len)
    1.97 +        return SECFailure;
    1.98 +
    1.99 +    PORT_Memcpy(item->data, buf, bytes);
   1.100 +    item->data += bytes;
   1.101 +    item->len -= bytes;
   1.102 +    return SECSuccess;
   1.103 +}
   1.104 +
   1.105 +/*
   1.106 + * Write a number in network byte order. Using this function means the
   1.107 + * SECItem structure cannot be freed.  The caller is expected to call
   1.108 + * this function on a shallow copy of the structure.
   1.109 + */
   1.110 +static SECStatus
   1.111 +ssl3_AppendNumberToItem(SECItem *item, PRUint32 num, PRInt32 lenSize)
   1.112 +{
   1.113 +    SECStatus rv;
   1.114 +    PRUint8   b[4];
   1.115 +    PRUint8 * p = b;
   1.116 +
   1.117 +    switch (lenSize) {
   1.118 +    case 4:
   1.119 +        *p++ = (PRUint8) (num >> 24);
   1.120 +    case 3:
   1.121 +        *p++ = (PRUint8) (num >> 16);
   1.122 +    case 2:
   1.123 +        *p++ = (PRUint8) (num >> 8);
   1.124 +    case 1:
   1.125 +        *p = (PRUint8) num;
   1.126 +    }
   1.127 +    rv = ssl3_AppendToItem(item, &b[0], lenSize);
   1.128 +    return rv;
   1.129 +}
   1.130 +
   1.131 +static SECStatus ssl3_SessionTicketShutdown(void* appData, void* nssData)
   1.132 +{
   1.133 +    if (session_ticket_enc_key_pkcs11) {
   1.134 +        PK11_FreeSymKey(session_ticket_enc_key_pkcs11);
   1.135 +        session_ticket_enc_key_pkcs11 = NULL;
   1.136 +    }
   1.137 +    if (session_ticket_mac_key_pkcs11) {
   1.138 +        PK11_FreeSymKey(session_ticket_mac_key_pkcs11);
   1.139 +        session_ticket_mac_key_pkcs11 = NULL;
   1.140 +    }
   1.141 +    PORT_Memset(&generate_session_keys_once, 0,
   1.142 +        sizeof(generate_session_keys_once));
   1.143 +    return SECSuccess;
   1.144 +}
   1.145 +
   1.146 +
   1.147 +static PRStatus
   1.148 +ssl3_GenerateSessionTicketKeysPKCS11(void *data)
   1.149 +{
   1.150 +    SECStatus rv;
   1.151 +    sslSocket *ss = (sslSocket *)data;
   1.152 +    SECKEYPrivateKey *svrPrivKey = ss->serverCerts[kt_rsa].SERVERKEY;
   1.153 +    SECKEYPublicKey *svrPubKey = ss->serverCerts[kt_rsa].serverKeyPair->pubKey;
   1.154 +
   1.155 +    if (svrPrivKey == NULL || svrPubKey == NULL) {
   1.156 +        SSL_DBG(("%d: SSL[%d]: Pub or priv key(s) is NULL.",
   1.157 +                        SSL_GETPID(), ss->fd));
   1.158 +        goto loser;
   1.159 +    }
   1.160 +
   1.161 +    /* Get a copy of the session keys from shared memory. */
   1.162 +    PORT_Memcpy(key_name, SESS_TICKET_KEY_NAME_PREFIX,
   1.163 +        sizeof(SESS_TICKET_KEY_NAME_PREFIX));
   1.164 +    if (!ssl_GetSessionTicketKeysPKCS11(svrPrivKey, svrPubKey,
   1.165 +            ss->pkcs11PinArg, &key_name[SESS_TICKET_KEY_NAME_PREFIX_LEN],
   1.166 +            &session_ticket_enc_key_pkcs11, &session_ticket_mac_key_pkcs11))
   1.167 +        return PR_FAILURE;
   1.168 +
   1.169 +    rv = NSS_RegisterShutdown(ssl3_SessionTicketShutdown, NULL);
   1.170 +    if (rv != SECSuccess)
   1.171 +        goto loser;
   1.172 +
   1.173 +    return PR_SUCCESS;
   1.174 +
   1.175 +loser:
   1.176 +    ssl3_SessionTicketShutdown(NULL, NULL);
   1.177 +    return PR_FAILURE;
   1.178 +}
   1.179 +
   1.180 +static SECStatus
   1.181 +ssl3_GetSessionTicketKeysPKCS11(sslSocket *ss, PK11SymKey **aes_key,
   1.182 +                                PK11SymKey **mac_key)
   1.183 +{
   1.184 +    if (PR_CallOnceWithArg(&generate_session_keys_once,
   1.185 +            ssl3_GenerateSessionTicketKeysPKCS11, ss) != PR_SUCCESS)
   1.186 +        return SECFailure;
   1.187 +
   1.188 +    if (session_ticket_enc_key_pkcs11 == NULL ||
   1.189 +        session_ticket_mac_key_pkcs11 == NULL)
   1.190 +        return SECFailure;
   1.191 +
   1.192 +    *aes_key = session_ticket_enc_key_pkcs11;
   1.193 +    *mac_key = session_ticket_mac_key_pkcs11;
   1.194 +    return SECSuccess;
   1.195 +}
   1.196 +
   1.197 +#ifndef NO_PKCS11_BYPASS
   1.198 +static PRStatus
   1.199 +ssl3_GenerateSessionTicketKeys(void)
   1.200 +{
   1.201 +    PORT_Memcpy(key_name, SESS_TICKET_KEY_NAME_PREFIX,
   1.202 +        sizeof(SESS_TICKET_KEY_NAME_PREFIX));
   1.203 +
   1.204 +    if (!ssl_GetSessionTicketKeys(&key_name[SESS_TICKET_KEY_NAME_PREFIX_LEN],
   1.205 +            session_ticket_enc_key, session_ticket_mac_key))
   1.206 +        return PR_FAILURE;
   1.207 +
   1.208 +    session_ticket_keys_initialized = PR_TRUE;
   1.209 +    return PR_SUCCESS;
   1.210 +}
   1.211 +
   1.212 +static SECStatus
   1.213 +ssl3_GetSessionTicketKeys(const unsigned char **aes_key,
   1.214 +    PRUint32 *aes_key_length, const unsigned char **mac_key,
   1.215 +    PRUint32 *mac_key_length)
   1.216 +{
   1.217 +    if (PR_CallOnce(&generate_session_keys_once,
   1.218 +            ssl3_GenerateSessionTicketKeys) != PR_SUCCESS)
   1.219 +        return SECFailure;
   1.220 +
   1.221 +    if (!session_ticket_keys_initialized)
   1.222 +        return SECFailure;
   1.223 +
   1.224 +    *aes_key = session_ticket_enc_key;
   1.225 +    *aes_key_length = sizeof(session_ticket_enc_key);
   1.226 +    *mac_key = session_ticket_mac_key;
   1.227 +    *mac_key_length = sizeof(session_ticket_mac_key);
   1.228 +
   1.229 +    return SECSuccess;
   1.230 +}
   1.231 +#endif
   1.232 +
   1.233 +/* Table of handlers for received TLS hello extensions, one per extension.
   1.234 + * In the second generation, this table will be dynamic, and functions
   1.235 + * will be registered here.
   1.236 + */
   1.237 +/* This table is used by the server, to handle client hello extensions. */
   1.238 +static const ssl3HelloExtensionHandler clientHelloHandlers[] = {
   1.239 +    { ssl_server_name_xtn,        &ssl3_HandleServerNameXtn },
   1.240 +#ifndef NSS_DISABLE_ECC
   1.241 +    { ssl_elliptic_curves_xtn,    &ssl3_HandleSupportedCurvesXtn },
   1.242 +    { ssl_ec_point_formats_xtn,   &ssl3_HandleSupportedPointFormatsXtn },
   1.243 +#endif
   1.244 +    { ssl_session_ticket_xtn,     &ssl3_ServerHandleSessionTicketXtn },
   1.245 +    { ssl_renegotiation_info_xtn, &ssl3_HandleRenegotiationInfoXtn },
   1.246 +    { ssl_next_proto_nego_xtn,    &ssl3_ServerHandleNextProtoNegoXtn },
   1.247 +    { ssl_app_layer_protocol_xtn, &ssl3_ServerHandleAppProtoXtn },
   1.248 +    { ssl_use_srtp_xtn,           &ssl3_HandleUseSRTPXtn },
   1.249 +    { ssl_cert_status_xtn,        &ssl3_ServerHandleStatusRequestXtn },
   1.250 +    { ssl_signature_algorithms_xtn, &ssl3_ServerHandleSigAlgsXtn },
   1.251 +    { -1, NULL }
   1.252 +};
   1.253 +
   1.254 +/* These two tables are used by the client, to handle server hello
   1.255 + * extensions. */
   1.256 +static const ssl3HelloExtensionHandler serverHelloHandlersTLS[] = {
   1.257 +    { ssl_server_name_xtn,        &ssl3_HandleServerNameXtn },
   1.258 +    /* TODO: add a handler for ssl_ec_point_formats_xtn */
   1.259 +    { ssl_session_ticket_xtn,     &ssl3_ClientHandleSessionTicketXtn },
   1.260 +    { ssl_renegotiation_info_xtn, &ssl3_HandleRenegotiationInfoXtn },
   1.261 +    { ssl_next_proto_nego_xtn,    &ssl3_ClientHandleNextProtoNegoXtn },
   1.262 +    { ssl_app_layer_protocol_xtn, &ssl3_ClientHandleAppProtoXtn },
   1.263 +    { ssl_use_srtp_xtn,           &ssl3_HandleUseSRTPXtn },
   1.264 +    { ssl_cert_status_xtn,        &ssl3_ClientHandleStatusRequestXtn },
   1.265 +    { -1, NULL }
   1.266 +};
   1.267 +
   1.268 +static const ssl3HelloExtensionHandler serverHelloHandlersSSL3[] = {
   1.269 +    { ssl_renegotiation_info_xtn, &ssl3_HandleRenegotiationInfoXtn },
   1.270 +    { -1, NULL }
   1.271 +};
   1.272 +
   1.273 +/* Tables of functions to format TLS hello extensions, one function per
   1.274 + * extension.
   1.275 + * These static tables are for the formatting of client hello extensions.
   1.276 + * The server's table of hello senders is dynamic, in the socket struct,
   1.277 + * and sender functions are registered there.
   1.278 + */
   1.279 +static const
   1.280 +ssl3HelloExtensionSender clientHelloSendersTLS[SSL_MAX_EXTENSIONS] = {
   1.281 +    { ssl_server_name_xtn,        &ssl3_SendServerNameXtn        },
   1.282 +    { ssl_renegotiation_info_xtn, &ssl3_SendRenegotiationInfoXtn },
   1.283 +#ifndef NSS_DISABLE_ECC
   1.284 +    { ssl_elliptic_curves_xtn,    &ssl3_SendSupportedCurvesXtn },
   1.285 +    { ssl_ec_point_formats_xtn,   &ssl3_SendSupportedPointFormatsXtn },
   1.286 +#endif
   1.287 +    { ssl_session_ticket_xtn,     &ssl3_SendSessionTicketXtn },
   1.288 +    { ssl_next_proto_nego_xtn,    &ssl3_ClientSendNextProtoNegoXtn },
   1.289 +    { ssl_app_layer_protocol_xtn, &ssl3_ClientSendAppProtoXtn },
   1.290 +    { ssl_use_srtp_xtn,           &ssl3_SendUseSRTPXtn },
   1.291 +    { ssl_cert_status_xtn,        &ssl3_ClientSendStatusRequestXtn },
   1.292 +    { ssl_signature_algorithms_xtn, &ssl3_ClientSendSigAlgsXtn }
   1.293 +    /* any extra entries will appear as { 0, NULL }    */
   1.294 +};
   1.295 +
   1.296 +static const
   1.297 +ssl3HelloExtensionSender clientHelloSendersSSL3[SSL_MAX_EXTENSIONS] = {
   1.298 +    { ssl_renegotiation_info_xtn, &ssl3_SendRenegotiationInfoXtn }
   1.299 +    /* any extra entries will appear as { 0, NULL }    */
   1.300 +};
   1.301 +
   1.302 +static PRBool
   1.303 +arrayContainsExtension(const PRUint16 *array, PRUint32 len, PRUint16 ex_type)
   1.304 +{
   1.305 +    int i;
   1.306 +    for (i = 0; i < len; i++) {
   1.307 +        if (ex_type == array[i])
   1.308 +            return PR_TRUE;
   1.309 +    }
   1.310 +    return PR_FALSE;
   1.311 +}
   1.312 +
   1.313 +PRBool
   1.314 +ssl3_ExtensionNegotiated(sslSocket *ss, PRUint16 ex_type) {
   1.315 +    TLSExtensionData *xtnData = &ss->xtnData;
   1.316 +    return arrayContainsExtension(xtnData->negotiated,
   1.317 +                                  xtnData->numNegotiated, ex_type);
   1.318 +}
   1.319 +
   1.320 +static PRBool
   1.321 +ssl3_ClientExtensionAdvertised(sslSocket *ss, PRUint16 ex_type) {
   1.322 +    TLSExtensionData *xtnData = &ss->xtnData;
   1.323 +    return arrayContainsExtension(xtnData->advertised,
   1.324 +                                  xtnData->numAdvertised, ex_type);
   1.325 +}
   1.326 +
   1.327 +/* Format an SNI extension, using the name from the socket's URL,
   1.328 + * unless that name is a dotted decimal string.
   1.329 + * Used by client and server.
   1.330 + */
   1.331 +PRInt32
   1.332 +ssl3_SendServerNameXtn(sslSocket * ss, PRBool append,
   1.333 +                       PRUint32 maxBytes)
   1.334 +{
   1.335 +    SECStatus rv;
   1.336 +    if (!ss)
   1.337 +        return 0;
   1.338 +    if (!ss->sec.isServer) {
   1.339 +        PRUint32 len;
   1.340 +        PRNetAddr netAddr;
   1.341 +
   1.342 +        /* must have a hostname */
   1.343 +        if (!ss->url || !ss->url[0])
   1.344 +            return 0;
   1.345 +        /* must not be an IPv4 or IPv6 address */
   1.346 +        if (PR_SUCCESS == PR_StringToNetAddr(ss->url, &netAddr)) {
   1.347 +            /* is an IP address (v4 or v6) */
   1.348 +            return 0;
   1.349 +        }
   1.350 +        len  = PORT_Strlen(ss->url);
   1.351 +        if (append && maxBytes >= len + 9) {
   1.352 +            /* extension_type */
   1.353 +            rv = ssl3_AppendHandshakeNumber(ss, ssl_server_name_xtn, 2);
   1.354 +            if (rv != SECSuccess) return -1;
   1.355 +            /* length of extension_data */
   1.356 +            rv = ssl3_AppendHandshakeNumber(ss, len + 5, 2);
   1.357 +            if (rv != SECSuccess) return -1;
   1.358 +            /* length of server_name_list */
   1.359 +            rv = ssl3_AppendHandshakeNumber(ss, len + 3, 2);
   1.360 +            if (rv != SECSuccess) return -1;
   1.361 +            /* Name Type (sni_host_name) */
   1.362 +            rv = ssl3_AppendHandshake(ss,       "\0",    1);
   1.363 +            if (rv != SECSuccess) return -1;
   1.364 +            /* HostName (length and value) */
   1.365 +            rv = ssl3_AppendHandshakeVariable(ss, (PRUint8 *)ss->url, len, 2);
   1.366 +            if (rv != SECSuccess) return -1;
   1.367 +            if (!ss->sec.isServer) {
   1.368 +                TLSExtensionData *xtnData = &ss->xtnData;
   1.369 +                xtnData->advertised[xtnData->numAdvertised++] =
   1.370 +                    ssl_server_name_xtn;
   1.371 +            }
   1.372 +        }
   1.373 +        return len + 9;
   1.374 +    }
   1.375 +    /* Server side */
   1.376 +    if (append && maxBytes >= 4) {
   1.377 +        rv = ssl3_AppendHandshakeNumber(ss, ssl_server_name_xtn, 2);
   1.378 +        if (rv != SECSuccess)  return -1;
   1.379 +        /* length of extension_data */
   1.380 +        rv = ssl3_AppendHandshakeNumber(ss, 0, 2);
   1.381 +        if (rv != SECSuccess) return -1;
   1.382 +    }
   1.383 +    return 4;
   1.384 +}
   1.385 +
   1.386 +/* handle an incoming SNI extension, by ignoring it. */
   1.387 +SECStatus
   1.388 +ssl3_HandleServerNameXtn(sslSocket * ss, PRUint16 ex_type, SECItem *data)
   1.389 +{
   1.390 +    SECItem *names = NULL;
   1.391 +    PRUint32 listCount = 0, namesPos = 0, i;
   1.392 +    TLSExtensionData *xtnData = &ss->xtnData;
   1.393 +    SECItem  ldata;
   1.394 +    PRInt32  listLenBytes = 0;
   1.395 +
   1.396 +    if (!ss->sec.isServer) {
   1.397 +        /* Verify extension_data is empty. */
   1.398 +        if (data->data || data->len ||
   1.399 +            !ssl3_ExtensionNegotiated(ss, ssl_server_name_xtn)) {
   1.400 +            /* malformed or was not initiated by the client.*/
   1.401 +            return SECFailure;
   1.402 +        }
   1.403 +        return SECSuccess;
   1.404 +    }
   1.405 +
   1.406 +    /* Server side - consume client data and register server sender. */
   1.407 +    /* do not parse the data if don't have user extension handling function. */
   1.408 +    if (!ss->sniSocketConfig) {
   1.409 +        return SECSuccess;
   1.410 +    }
   1.411 +    /* length of server_name_list */
   1.412 +    listLenBytes = ssl3_ConsumeHandshakeNumber(ss, 2, &data->data, &data->len);
   1.413 +    if (listLenBytes == 0 || listLenBytes != data->len) {
   1.414 +        return SECFailure;
   1.415 +    }
   1.416 +    ldata = *data;
   1.417 +    /* Calculate the size of the array.*/
   1.418 +    while (listLenBytes > 0) {
   1.419 +        SECItem litem;
   1.420 +        SECStatus rv;
   1.421 +        PRInt32  type;
   1.422 +        /* Name Type (sni_host_name) */
   1.423 +        type = ssl3_ConsumeHandshakeNumber(ss, 1, &ldata.data, &ldata.len);
   1.424 +        if (!ldata.len) {
   1.425 +            return SECFailure;
   1.426 +        }
   1.427 +        rv = ssl3_ConsumeHandshakeVariable(ss, &litem, 2, &ldata.data, &ldata.len);
   1.428 +        if (rv != SECSuccess) {
   1.429 +            return SECFailure;
   1.430 +        }
   1.431 +        /* Adjust total length for cunsumed item, item len and type.*/
   1.432 +        listLenBytes -= litem.len + 3;
   1.433 +        if (listLenBytes > 0 && !ldata.len) {
   1.434 +            return SECFailure;
   1.435 +        }
   1.436 +        listCount += 1;
   1.437 +    }
   1.438 +    if (!listCount) {
   1.439 +        return SECFailure;
   1.440 +    }
   1.441 +    names = PORT_ZNewArray(SECItem, listCount);
   1.442 +    if (!names) {
   1.443 +        return SECFailure;
   1.444 +    }
   1.445 +    for (i = 0;i < listCount;i++) {
   1.446 +        int j;
   1.447 +        PRInt32  type;
   1.448 +        SECStatus rv;
   1.449 +        PRBool nametypePresent = PR_FALSE;
   1.450 +        /* Name Type (sni_host_name) */
   1.451 +        type = ssl3_ConsumeHandshakeNumber(ss, 1, &data->data, &data->len);
   1.452 +        /* Check if we have such type in the list */
   1.453 +        for (j = 0;j < listCount && names[j].data;j++) {
   1.454 +            if (names[j].type == type) {
   1.455 +                nametypePresent = PR_TRUE;
   1.456 +                break;
   1.457 +            }
   1.458 +        }
   1.459 +        /* HostName (length and value) */
   1.460 +        rv = ssl3_ConsumeHandshakeVariable(ss, &names[namesPos], 2,
   1.461 +                                           &data->data, &data->len);
   1.462 +        if (rv != SECSuccess) {
   1.463 +            goto loser;
   1.464 +        }
   1.465 +        if (nametypePresent == PR_FALSE) {
   1.466 +            namesPos += 1;
   1.467 +        }
   1.468 +    }
   1.469 +    /* Free old and set the new data. */
   1.470 +    if (xtnData->sniNameArr) {
   1.471 +        PORT_Free(ss->xtnData.sniNameArr);
   1.472 +    }
   1.473 +    xtnData->sniNameArr = names;
   1.474 +    xtnData->sniNameArrSize = namesPos;
   1.475 +    xtnData->negotiated[xtnData->numNegotiated++] = ssl_server_name_xtn;
   1.476 +
   1.477 +    return SECSuccess;
   1.478 +
   1.479 +loser:
   1.480 +    PORT_Free(names);
   1.481 +    return SECFailure;
   1.482 +}
   1.483 +
   1.484 +/* Called by both clients and servers.
   1.485 + * Clients sends a filled in session ticket if one is available, and otherwise
   1.486 + * sends an empty ticket.  Servers always send empty tickets.
   1.487 + */
   1.488 +PRInt32
   1.489 +ssl3_SendSessionTicketXtn(
   1.490 +                        sslSocket * ss,
   1.491 +                        PRBool      append,
   1.492 +                        PRUint32    maxBytes)
   1.493 +{
   1.494 +    PRInt32 extension_length;
   1.495 +    NewSessionTicket *session_ticket = NULL;
   1.496 +    sslSessionID *sid = ss->sec.ci.sid;
   1.497 +
   1.498 +    /* Ignore the SessionTicket extension if processing is disabled. */
   1.499 +    if (!ss->opt.enableSessionTickets)
   1.500 +        return 0;
   1.501 +
   1.502 +    /* Empty extension length = extension_type (2-bytes) +
   1.503 +     * length(extension_data) (2-bytes)
   1.504 +     */
   1.505 +    extension_length = 4;
   1.506 +
   1.507 +    /* If we are a client then send a session ticket if one is availble.
   1.508 +     * Servers that support the extension and are willing to negotiate the
   1.509 +     * the extension always respond with an empty extension.
   1.510 +     */
   1.511 +    if (!ss->sec.isServer) {
   1.512 +        /* The caller must be holding sid->u.ssl3.lock for reading. We cannot
   1.513 +         * just acquire and release the lock within this function because the
   1.514 +         * caller will call this function twice, and we need the inputs to be
   1.515 +         * consistent between the two calls. Note that currently the caller
   1.516 +         * will only be holding the lock when we are the client and when we're
   1.517 +         * attempting to resume an existing session.
   1.518 +         */
   1.519 +
   1.520 +        session_ticket = &sid->u.ssl3.locked.sessionTicket;
   1.521 +        if (session_ticket->ticket.data) {
   1.522 +            if (ss->xtnData.ticketTimestampVerified) {
   1.523 +                extension_length += session_ticket->ticket.len;
   1.524 +            } else if (!append &&
   1.525 +                (session_ticket->ticket_lifetime_hint == 0 ||
   1.526 +                (session_ticket->ticket_lifetime_hint +
   1.527 +                    session_ticket->received_timestamp > ssl_Time()))) {
   1.528 +                extension_length += session_ticket->ticket.len;
   1.529 +                ss->xtnData.ticketTimestampVerified = PR_TRUE;
   1.530 +            }
   1.531 +        }
   1.532 +    }
   1.533 +
   1.534 +    if (append && maxBytes >= extension_length) {
   1.535 +        SECStatus rv;
   1.536 +        /* extension_type */
   1.537 +        rv = ssl3_AppendHandshakeNumber(ss, ssl_session_ticket_xtn, 2);
   1.538 +        if (rv != SECSuccess)
   1.539 +            goto loser;
   1.540 +        if (session_ticket && session_ticket->ticket.data &&
   1.541 +            ss->xtnData.ticketTimestampVerified) {
   1.542 +            rv = ssl3_AppendHandshakeVariable(ss, session_ticket->ticket.data,
   1.543 +                session_ticket->ticket.len, 2);
   1.544 +            ss->xtnData.ticketTimestampVerified = PR_FALSE;
   1.545 +            ss->xtnData.sentSessionTicketInClientHello = PR_TRUE;
   1.546 +        } else {
   1.547 +            rv = ssl3_AppendHandshakeNumber(ss, 0, 2);
   1.548 +        }
   1.549 +        if (rv != SECSuccess)
   1.550 +            goto loser;
   1.551 +
   1.552 +        if (!ss->sec.isServer) {
   1.553 +            TLSExtensionData *xtnData = &ss->xtnData;
   1.554 +            xtnData->advertised[xtnData->numAdvertised++] =
   1.555 +                ssl_session_ticket_xtn;
   1.556 +        }
   1.557 +    } else if (maxBytes < extension_length) {
   1.558 +        PORT_Assert(0);
   1.559 +        return 0;
   1.560 +    }
   1.561 +    return extension_length;
   1.562 +
   1.563 + loser:
   1.564 +    ss->xtnData.ticketTimestampVerified = PR_FALSE;
   1.565 +    return -1;
   1.566 +}
   1.567 +
   1.568 +/* handle an incoming Next Protocol Negotiation extension. */
   1.569 +static SECStatus
   1.570 +ssl3_ServerHandleNextProtoNegoXtn(sslSocket * ss, PRUint16 ex_type,
   1.571 +                                  SECItem *data)
   1.572 +{
   1.573 +    if (ss->firstHsDone || data->len != 0) {
   1.574 +        /* Clients MUST send an empty NPN extension, if any. */
   1.575 +        PORT_SetError(SSL_ERROR_NEXT_PROTOCOL_DATA_INVALID);
   1.576 +        return SECFailure;
   1.577 +    }
   1.578 +
   1.579 +    ss->xtnData.negotiated[ss->xtnData.numNegotiated++] = ex_type;
   1.580 +
   1.581 +    /* TODO: server side NPN support would require calling
   1.582 +     * ssl3_RegisterServerHelloExtensionSender here in order to echo the
   1.583 +     * extension back to the client. */
   1.584 +
   1.585 +    return SECSuccess;
   1.586 +}
   1.587 +
   1.588 +/* ssl3_ValidateNextProtoNego checks that the given block of data is valid: none
   1.589 + * of the lengths may be 0 and the sum of the lengths must equal the length of
   1.590 + * the block. */
   1.591 +SECStatus
   1.592 +ssl3_ValidateNextProtoNego(const unsigned char* data, unsigned int length)
   1.593 +{
   1.594 +    unsigned int offset = 0;
   1.595 +
   1.596 +    while (offset < length) {
   1.597 +        unsigned int newOffset = offset + 1 + (unsigned int) data[offset];
   1.598 +        /* Reject embedded nulls to protect against buggy applications that
   1.599 +         * store protocol identifiers in null-terminated strings.
   1.600 +         */
   1.601 +        if (newOffset > length || data[offset] == 0) {
   1.602 +            PORT_SetError(SSL_ERROR_NEXT_PROTOCOL_DATA_INVALID);
   1.603 +            return SECFailure;
   1.604 +        }
   1.605 +        offset = newOffset;
   1.606 +    }
   1.607 +
   1.608 +    if (offset > length) {
   1.609 +        PORT_SetError(SSL_ERROR_NEXT_PROTOCOL_DATA_INVALID);
   1.610 +        return SECFailure;
   1.611 +    }
   1.612 +
   1.613 +    return SECSuccess;
   1.614 +}
   1.615 +
   1.616 +/* protocol selection handler for ALPN (server side) and NPN (client side) */
   1.617 +static SECStatus
   1.618 +ssl3_SelectAppProtocol(sslSocket *ss, PRUint16 ex_type, SECItem *data)
   1.619 +{
   1.620 +    SECStatus rv;
   1.621 +    unsigned char resultBuffer[255];
   1.622 +    SECItem result = { siBuffer, resultBuffer, 0 };
   1.623 +
   1.624 +    rv = ssl3_ValidateNextProtoNego(data->data, data->len);
   1.625 +    if (rv != SECSuccess)
   1.626 +        return rv;
   1.627 +
   1.628 +    PORT_Assert(ss->nextProtoCallback);
   1.629 +    rv = ss->nextProtoCallback(ss->nextProtoArg, ss->fd, data->data, data->len,
   1.630 +                               result.data, &result.len, sizeof resultBuffer);
   1.631 +    if (rv != SECSuccess)
   1.632 +        return rv;
   1.633 +    /* If the callback wrote more than allowed to |result| it has corrupted our
   1.634 +     * stack. */
   1.635 +    if (result.len > sizeof resultBuffer) {
   1.636 +        PORT_SetError(SEC_ERROR_OUTPUT_LEN);
   1.637 +        return SECFailure;
   1.638 +    }
   1.639 +
   1.640 +    if (ex_type == ssl_app_layer_protocol_xtn &&
   1.641 +        ss->ssl3.nextProtoState != SSL_NEXT_PROTO_NEGOTIATED) {
   1.642 +        /* The callback might say OK, but then it's picked a default.
   1.643 +         * That's OK for NPN, but not ALPN. */
   1.644 +        SECITEM_FreeItem(&ss->ssl3.nextProto, PR_FALSE);
   1.645 +        PORT_SetError(SSL_ERROR_NEXT_PROTOCOL_NO_PROTOCOL);
   1.646 +        (void)SSL3_SendAlert(ss, alert_fatal, no_application_protocol);
   1.647 +        return SECFailure;
   1.648 +    }
   1.649 +
   1.650 +    ss->xtnData.negotiated[ss->xtnData.numNegotiated++] = ex_type;
   1.651 +
   1.652 +    SECITEM_FreeItem(&ss->ssl3.nextProto, PR_FALSE);
   1.653 +    return SECITEM_CopyItem(NULL, &ss->ssl3.nextProto, &result);
   1.654 +}
   1.655 +
   1.656 +/* handle an incoming ALPN extension at the server */
   1.657 +static SECStatus
   1.658 +ssl3_ServerHandleAppProtoXtn(sslSocket *ss, PRUint16 ex_type, SECItem *data)
   1.659 +{
   1.660 +    int count;
   1.661 +    SECStatus rv;
   1.662 +
   1.663 +    /* We expressly don't want to allow ALPN on renegotiation,
   1.664 +     * despite it being permitted by the spec. */
   1.665 +    if (ss->firstHsDone || data->len == 0) {
   1.666 +        /* Clients MUST send a non-empty ALPN extension. */
   1.667 +        PORT_SetError(SSL_ERROR_NEXT_PROTOCOL_DATA_INVALID);
   1.668 +        return SECFailure;
   1.669 +    }
   1.670 +
   1.671 +    /* unlike NPN, ALPN has extra redundant length information so that
   1.672 +     * the extension is the same in both ClientHello and ServerHello */
   1.673 +    count = ssl3_ConsumeHandshakeNumber(ss, 2, &data->data, &data->len);
   1.674 +    if (count < 0) {
   1.675 +        return SECFailure; /* fatal alert was sent */
   1.676 +    }
   1.677 +    if (count != data->len) {
   1.678 +        return ssl3_DecodeError(ss);
   1.679 +    }
   1.680 +
   1.681 +    if (!ss->nextProtoCallback) {
   1.682 +        /* we're not configured for it */
   1.683 +        return SECSuccess;
   1.684 +    }
   1.685 +
   1.686 +    rv = ssl3_SelectAppProtocol(ss, ex_type, data);
   1.687 +    if (rv != SECSuccess) {
   1.688 +      return rv;
   1.689 +    }
   1.690 +
   1.691 +    /* prepare to send back a response, if we negotiated */
   1.692 +    if (ss->ssl3.nextProtoState == SSL_NEXT_PROTO_NEGOTIATED) {
   1.693 +        return ssl3_RegisterServerHelloExtensionSender(
   1.694 +            ss, ex_type, ssl3_ServerSendAppProtoXtn);
   1.695 +    }
   1.696 +    return SECSuccess;
   1.697 +}
   1.698 +
   1.699 +static SECStatus
   1.700 +ssl3_ClientHandleNextProtoNegoXtn(sslSocket *ss, PRUint16 ex_type,
   1.701 +                                  SECItem *data)
   1.702 +{
   1.703 +    PORT_Assert(!ss->firstHsDone);
   1.704 +
   1.705 +    if (ssl3_ExtensionNegotiated(ss, ssl_app_layer_protocol_xtn)) {
   1.706 +        /* If the server negotiated ALPN then it has already told us what
   1.707 +         * protocol to use, so it doesn't make sense for us to try to negotiate
   1.708 +         * a different one by sending the NPN handshake message. However, if
   1.709 +         * we've negotiated NPN then we're required to send the NPN handshake
   1.710 +         * message. Thus, these two extensions cannot both be negotiated on the
   1.711 +         * same connection. */
   1.712 +        PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
   1.713 +        return SECFailure;
   1.714 +    }
   1.715 +
   1.716 +    /* We should only get this call if we sent the extension, so
   1.717 +     * ss->nextProtoCallback needs to be non-NULL.  However, it is possible
   1.718 +     * that an application erroneously cleared the callback between the time
   1.719 +     * we sent the ClientHello and now. */
   1.720 +    if (!ss->nextProtoCallback) {
   1.721 +        PORT_SetError(SSL_ERROR_NEXT_PROTOCOL_NO_CALLBACK);
   1.722 +        return SECFailure;
   1.723 +    }
   1.724 +
   1.725 +    return ssl3_SelectAppProtocol(ss, ex_type, data);
   1.726 +}
   1.727 +
   1.728 +static SECStatus
   1.729 +ssl3_ClientHandleAppProtoXtn(sslSocket *ss, PRUint16 ex_type, SECItem *data)
   1.730 +{
   1.731 +    const unsigned char* d = data->data;
   1.732 +    PRUint16 name_list_len;
   1.733 +    SECItem protocol_name;
   1.734 +
   1.735 +    if (ssl3_ExtensionNegotiated(ss, ssl_next_proto_nego_xtn)) {
   1.736 +        PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
   1.737 +        return SECFailure;
   1.738 +    }
   1.739 +
   1.740 +    /* The extension data from the server has the following format:
   1.741 +     *   uint16 name_list_len;
   1.742 +     *   uint8 len;
   1.743 +     *   uint8 protocol_name[len]; */
   1.744 +    if (data->len < 4 || data->len > 2 + 1 + 255) {
   1.745 +        PORT_SetError(SSL_ERROR_NEXT_PROTOCOL_DATA_INVALID);
   1.746 +        return SECFailure;
   1.747 +    }
   1.748 +
   1.749 +    name_list_len = ((PRUint16) d[0]) << 8 |
   1.750 +                    ((PRUint16) d[1]);
   1.751 +    if (name_list_len != data->len - 2 || d[2] != data->len - 3) {
   1.752 +        PORT_SetError(SSL_ERROR_NEXT_PROTOCOL_DATA_INVALID);
   1.753 +        return SECFailure;
   1.754 +    }
   1.755 +
   1.756 +    protocol_name.data = data->data + 3;
   1.757 +    protocol_name.len = data->len - 3;
   1.758 +
   1.759 +    SECITEM_FreeItem(&ss->ssl3.nextProto, PR_FALSE);
   1.760 +    ss->ssl3.nextProtoState = SSL_NEXT_PROTO_SELECTED;
   1.761 +    ss->xtnData.negotiated[ss->xtnData.numNegotiated++] = ex_type;
   1.762 +    return SECITEM_CopyItem(NULL, &ss->ssl3.nextProto, &protocol_name);
   1.763 +}
   1.764 +
   1.765 +static PRInt32
   1.766 +ssl3_ClientSendNextProtoNegoXtn(sslSocket * ss, PRBool append,
   1.767 +                                PRUint32 maxBytes)
   1.768 +{
   1.769 +    PRInt32 extension_length;
   1.770 +
   1.771 +    /* Renegotiations do not send this extension. */
   1.772 +    if (!ss->opt.enableNPN || !ss->nextProtoCallback || ss->firstHsDone) {
   1.773 +        return 0;
   1.774 +    }
   1.775 +
   1.776 +    extension_length = 4;
   1.777 +
   1.778 +    if (append && maxBytes >= extension_length) {
   1.779 +        SECStatus rv;
   1.780 +        rv = ssl3_AppendHandshakeNumber(ss, ssl_next_proto_nego_xtn, 2);
   1.781 +        if (rv != SECSuccess)
   1.782 +            goto loser;
   1.783 +        rv = ssl3_AppendHandshakeNumber(ss, 0, 2);
   1.784 +        if (rv != SECSuccess)
   1.785 +            goto loser;
   1.786 +        ss->xtnData.advertised[ss->xtnData.numAdvertised++] =
   1.787 +                ssl_next_proto_nego_xtn;
   1.788 +    } else if (maxBytes < extension_length) {
   1.789 +        return 0;
   1.790 +    }
   1.791 +
   1.792 +    return extension_length;
   1.793 +
   1.794 +loser:
   1.795 +    return -1;
   1.796 +}
   1.797 +
   1.798 +static PRInt32
   1.799 +ssl3_ClientSendAppProtoXtn(sslSocket * ss, PRBool append, PRUint32 maxBytes)
   1.800 +{
   1.801 +    PRInt32 extension_length;
   1.802 +    unsigned char *alpn_protos = NULL;
   1.803 +
   1.804 +    /* Renegotiations do not send this extension. */
   1.805 +    if (!ss->opt.enableALPN || !ss->opt.nextProtoNego.data || ss->firstHsDone) {
   1.806 +        return 0;
   1.807 +    }
   1.808 +
   1.809 +    extension_length = 2 /* extension type */ + 2 /* extension length */ +
   1.810 +                       2 /* protocol name list length */ +
   1.811 +                       ss->opt.nextProtoNego.len;
   1.812 +
   1.813 +    if (append && maxBytes >= extension_length) {
   1.814 +        /* NPN requires that the client's fallback protocol is first in the
   1.815 +         * list. However, ALPN sends protocols in preference order. So we
   1.816 +         * allocate a buffer and move the first protocol to the end of the
   1.817 +         * list. */
   1.818 +        SECStatus rv;
   1.819 +        const unsigned int len = ss->opt.nextProtoNego.len;
   1.820 +
   1.821 +        alpn_protos = PORT_Alloc(len);
   1.822 +        if (alpn_protos == NULL) {
   1.823 +            return SECFailure;
   1.824 +        }
   1.825 +        if (len > 0) {
   1.826 +            /* Each protocol string is prefixed with a single byte length. */
   1.827 +            unsigned int i = ss->opt.nextProtoNego.data[0] + 1;
   1.828 +            if (i <= len) {
   1.829 +                memcpy(alpn_protos, &ss->opt.nextProtoNego.data[i], len - i);
   1.830 +                memcpy(alpn_protos + len - i, ss->opt.nextProtoNego.data, i);
   1.831 +            } else {
   1.832 +                /* This seems to be invalid data so we'll send as-is. */
   1.833 +                memcpy(alpn_protos, ss->opt.nextProtoNego.data, len);
   1.834 +            }
   1.835 +        }
   1.836 +
   1.837 +        rv = ssl3_AppendHandshakeNumber(ss, ssl_app_layer_protocol_xtn, 2);
   1.838 +        if (rv != SECSuccess) {
   1.839 +            goto loser;
   1.840 +        }
   1.841 +        rv = ssl3_AppendHandshakeNumber(ss, extension_length - 4, 2);
   1.842 +        if (rv != SECSuccess) {
   1.843 +            goto loser;
   1.844 +        }
   1.845 +        rv = ssl3_AppendHandshakeVariable(ss, alpn_protos, len, 2);
   1.846 +        PORT_Free(alpn_protos);
   1.847 +        alpn_protos = NULL;
   1.848 +        if (rv != SECSuccess) {
   1.849 +            goto loser;
   1.850 +        }
   1.851 +        ss->xtnData.advertised[ss->xtnData.numAdvertised++] =
   1.852 +                ssl_app_layer_protocol_xtn;
   1.853 +    } else if (maxBytes < extension_length) {
   1.854 +        return 0;
   1.855 +    }
   1.856 +
   1.857 +    return extension_length;
   1.858 +
   1.859 +loser:
   1.860 +    if (alpn_protos) {
   1.861 +        PORT_Free(alpn_protos);
   1.862 +    }
   1.863 +    return -1;
   1.864 +}
   1.865 +
   1.866 +static PRInt32
   1.867 +ssl3_ServerSendAppProtoXtn(sslSocket * ss, PRBool append, PRUint32 maxBytes)
   1.868 +{
   1.869 +    PRInt32 extension_length;
   1.870 +
   1.871 +    /* we're in over our heads if any of these fail */
   1.872 +    PORT_Assert(ss->opt.enableALPN);
   1.873 +    PORT_Assert(ss->ssl3.nextProto.data);
   1.874 +    PORT_Assert(ss->ssl3.nextProto.len > 0);
   1.875 +    PORT_Assert(ss->ssl3.nextProtoState == SSL_NEXT_PROTO_NEGOTIATED);
   1.876 +    PORT_Assert(!ss->firstHsDone);
   1.877 +
   1.878 +    extension_length = 2 /* extension type */ + 2 /* extension length */ +
   1.879 +                       2 /* protocol name list */ + 1 /* name length */ +
   1.880 +                       ss->ssl3.nextProto.len;
   1.881 +
   1.882 +    if (append && maxBytes >= extension_length) {
   1.883 +        SECStatus rv;
   1.884 +        rv = ssl3_AppendHandshakeNumber(ss, ssl_app_layer_protocol_xtn, 2);
   1.885 +        if (rv != SECSuccess) {
   1.886 +            return -1;
   1.887 +        }
   1.888 +        rv = ssl3_AppendHandshakeNumber(ss, extension_length - 4, 2);
   1.889 +        if (rv != SECSuccess) {
   1.890 +            return -1;
   1.891 +        }
   1.892 +        rv = ssl3_AppendHandshakeNumber(ss, ss->ssl3.nextProto.len + 1, 2);
   1.893 +        if (rv != SECSuccess) {
   1.894 +            return -1;
   1.895 +        }
   1.896 +        rv = ssl3_AppendHandshakeVariable(ss, ss->ssl3.nextProto.data,
   1.897 +                                          ss->ssl3.nextProto.len, 1);
   1.898 +        if (rv != SECSuccess) {
   1.899 +            return -1;
   1.900 +        }
   1.901 +    } else if (maxBytes < extension_length) {
   1.902 +        return 0;
   1.903 +    }
   1.904 +
   1.905 +    return extension_length;
   1.906 +}
   1.907 +
   1.908 +static SECStatus
   1.909 +ssl3_ClientHandleStatusRequestXtn(sslSocket *ss, PRUint16 ex_type,
   1.910 +                                 SECItem *data)
   1.911 +{
   1.912 +    /* The echoed extension must be empty. */
   1.913 +    if (data->len != 0)
   1.914 +       return SECFailure;
   1.915 +
   1.916 +    /* Keep track of negotiated extensions. */
   1.917 +    ss->xtnData.negotiated[ss->xtnData.numNegotiated++] = ex_type;
   1.918 +
   1.919 +    return SECSuccess;
   1.920 +}
   1.921 +
   1.922 +static PRInt32
   1.923 +ssl3_ServerSendStatusRequestXtn(
   1.924 +                        sslSocket * ss,
   1.925 +                        PRBool      append,
   1.926 +                        PRUint32    maxBytes)
   1.927 +{
   1.928 +    PRInt32 extension_length;
   1.929 +    SECStatus rv;
   1.930 +    int i;
   1.931 +    PRBool haveStatus = PR_FALSE;
   1.932 +
   1.933 +    for (i = kt_null; i < kt_kea_size; i++) {
   1.934 +        /* TODO: This is a temporary workaround.
   1.935 +         *       The correct code needs to see if we have an OCSP response for
   1.936 +         *       the server certificate being used, rather than if we have any
   1.937 +         *       OCSP response. See also ssl3_SendCertificateStatus.
   1.938 +         */
   1.939 +        if (ss->certStatusArray[i] && ss->certStatusArray[i]->len) {
   1.940 +            haveStatus = PR_TRUE;
   1.941 +            break;
   1.942 +        }
   1.943 +    }
   1.944 +    if (!haveStatus)
   1.945 +        return 0;
   1.946 +
   1.947 +    extension_length = 2 + 2;
   1.948 +    if (append && maxBytes >= extension_length) {
   1.949 +        /* extension_type */
   1.950 +        rv = ssl3_AppendHandshakeNumber(ss, ssl_cert_status_xtn, 2);
   1.951 +        if (rv != SECSuccess)
   1.952 +            return -1;
   1.953 +        /* length of extension_data */
   1.954 +        rv = ssl3_AppendHandshakeNumber(ss, 0, 2);
   1.955 +        if (rv != SECSuccess)
   1.956 +            return -1;
   1.957 +    }
   1.958 +
   1.959 +    return extension_length;
   1.960 +}
   1.961 +
   1.962 +/* ssl3_ClientSendStatusRequestXtn builds the status_request extension on the
   1.963 + * client side. See RFC 4366 section 3.6. */
   1.964 +static PRInt32
   1.965 +ssl3_ClientSendStatusRequestXtn(sslSocket * ss, PRBool append,
   1.966 +                               PRUint32 maxBytes)
   1.967 +{
   1.968 +    PRInt32 extension_length;
   1.969 +
   1.970 +    if (!ss->opt.enableOCSPStapling)
   1.971 +       return 0;
   1.972 +
   1.973 +    /* extension_type (2-bytes) +
   1.974 +     * length(extension_data) (2-bytes) +
   1.975 +     * status_type (1) +
   1.976 +     * responder_id_list length (2) +
   1.977 +     * request_extensions length (2)
   1.978 +     */
   1.979 +    extension_length = 9;
   1.980 +
   1.981 +    if (append && maxBytes >= extension_length) {
   1.982 +       SECStatus rv;
   1.983 +       TLSExtensionData *xtnData;
   1.984 +
   1.985 +       /* extension_type */
   1.986 +       rv = ssl3_AppendHandshakeNumber(ss, ssl_cert_status_xtn, 2);
   1.987 +       if (rv != SECSuccess)
   1.988 +           return -1;
   1.989 +       rv = ssl3_AppendHandshakeNumber(ss, extension_length - 4, 2);
   1.990 +       if (rv != SECSuccess)
   1.991 +           return -1;
   1.992 +       rv = ssl3_AppendHandshakeNumber(ss, 1 /* status_type ocsp */, 1);
   1.993 +       if (rv != SECSuccess)
   1.994 +           return -1;
   1.995 +       /* A zero length responder_id_list means that the responders are
   1.996 +        * implicitly known to the server. */
   1.997 +       rv = ssl3_AppendHandshakeNumber(ss, 0, 2);
   1.998 +       if (rv != SECSuccess)
   1.999 +           return -1;
  1.1000 +       /* A zero length request_extensions means that there are no extensions.
  1.1001 +        * Specifically, we don't set the id-pkix-ocsp-nonce extension. This
  1.1002 +        * means that the server can replay a cached OCSP response to us. */
  1.1003 +       rv = ssl3_AppendHandshakeNumber(ss, 0, 2);
  1.1004 +       if (rv != SECSuccess)
  1.1005 +           return -1;
  1.1006 +
  1.1007 +       xtnData = &ss->xtnData;
  1.1008 +       xtnData->advertised[xtnData->numAdvertised++] = ssl_cert_status_xtn;
  1.1009 +    } else if (maxBytes < extension_length) {
  1.1010 +       PORT_Assert(0);
  1.1011 +       return 0;
  1.1012 +    }
  1.1013 +    return extension_length;
  1.1014 +}
  1.1015 +
  1.1016 +/*
  1.1017 + * NewSessionTicket
  1.1018 + * Called from ssl3_HandleFinished
  1.1019 + */
  1.1020 +SECStatus
  1.1021 +ssl3_SendNewSessionTicket(sslSocket *ss)
  1.1022 +{
  1.1023 +    int                  i;
  1.1024 +    SECStatus            rv;
  1.1025 +    NewSessionTicket     ticket;
  1.1026 +    SECItem              plaintext;
  1.1027 +    SECItem              plaintext_item = {0, NULL, 0};
  1.1028 +    SECItem              ciphertext     = {0, NULL, 0};
  1.1029 +    PRUint32             ciphertext_length;
  1.1030 +    PRBool               ms_is_wrapped;
  1.1031 +    unsigned char        wrapped_ms[SSL3_MASTER_SECRET_LENGTH];
  1.1032 +    SECItem              ms_item = {0, NULL, 0};
  1.1033 +    SSL3KEAType          effectiveExchKeyType = ssl_kea_null;
  1.1034 +    PRUint32             padding_length;
  1.1035 +    PRUint32             message_length;
  1.1036 +    PRUint32             cert_length;
  1.1037 +    PRUint8              length_buf[4];
  1.1038 +    PRUint32             now;
  1.1039 +    PK11SymKey          *aes_key_pkcs11;
  1.1040 +    PK11SymKey          *mac_key_pkcs11;
  1.1041 +#ifndef NO_PKCS11_BYPASS
  1.1042 +    const unsigned char *aes_key;
  1.1043 +    const unsigned char *mac_key;
  1.1044 +    PRUint32             aes_key_length;
  1.1045 +    PRUint32             mac_key_length;
  1.1046 +    PRUint64             aes_ctx_buf[MAX_CIPHER_CONTEXT_LLONGS];
  1.1047 +    AESContext          *aes_ctx;
  1.1048 +    const SECHashObject *hashObj = NULL;
  1.1049 +    PRUint64             hmac_ctx_buf[MAX_MAC_CONTEXT_LLONGS];
  1.1050 +    HMACContext         *hmac_ctx;
  1.1051 +#endif
  1.1052 +    CK_MECHANISM_TYPE    cipherMech = CKM_AES_CBC;
  1.1053 +    PK11Context         *aes_ctx_pkcs11;
  1.1054 +    CK_MECHANISM_TYPE    macMech = CKM_SHA256_HMAC;
  1.1055 +    PK11Context         *hmac_ctx_pkcs11;
  1.1056 +    unsigned char        computed_mac[TLS_EX_SESS_TICKET_MAC_LENGTH];
  1.1057 +    unsigned int         computed_mac_length;
  1.1058 +    unsigned char        iv[AES_BLOCK_SIZE];
  1.1059 +    SECItem              ivItem;
  1.1060 +    SECItem             *srvName = NULL;
  1.1061 +    PRUint32             srvNameLen = 0;
  1.1062 +    CK_MECHANISM_TYPE    msWrapMech = 0; /* dummy default value,
  1.1063 +                                          * must be >= 0 */
  1.1064 +
  1.1065 +    SSL_TRC(3, ("%d: SSL3[%d]: send session_ticket handshake",
  1.1066 +                SSL_GETPID(), ss->fd));
  1.1067 +
  1.1068 +    PORT_Assert( ss->opt.noLocks || ssl_HaveXmitBufLock(ss));
  1.1069 +    PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss));
  1.1070 +
  1.1071 +    ticket.ticket_lifetime_hint = TLS_EX_SESS_TICKET_LIFETIME_HINT;
  1.1072 +    cert_length = (ss->opt.requestCertificate && ss->sec.ci.sid->peerCert) ?
  1.1073 +        3 + ss->sec.ci.sid->peerCert->derCert.len : 0;
  1.1074 +
  1.1075 +    /* Get IV and encryption keys */
  1.1076 +    ivItem.data = iv;
  1.1077 +    ivItem.len = sizeof(iv);
  1.1078 +    rv = PK11_GenerateRandom(iv, sizeof(iv));
  1.1079 +    if (rv != SECSuccess) goto loser;
  1.1080 +
  1.1081 +#ifndef NO_PKCS11_BYPASS
  1.1082 +    if (ss->opt.bypassPKCS11) {
  1.1083 +        rv = ssl3_GetSessionTicketKeys(&aes_key, &aes_key_length,
  1.1084 +            &mac_key, &mac_key_length);
  1.1085 +    } else
  1.1086 +#endif
  1.1087 +    {
  1.1088 +        rv = ssl3_GetSessionTicketKeysPKCS11(ss, &aes_key_pkcs11,
  1.1089 +            &mac_key_pkcs11);
  1.1090 +    }
  1.1091 +    if (rv != SECSuccess) goto loser;
  1.1092 +
  1.1093 +    if (ss->ssl3.pwSpec->msItem.len && ss->ssl3.pwSpec->msItem.data) {
  1.1094 +        /* The master secret is available unwrapped. */
  1.1095 +        ms_item.data = ss->ssl3.pwSpec->msItem.data;
  1.1096 +        ms_item.len = ss->ssl3.pwSpec->msItem.len;
  1.1097 +        ms_is_wrapped = PR_FALSE;
  1.1098 +    } else {
  1.1099 +        /* Extract the master secret wrapped. */
  1.1100 +        sslSessionID sid;
  1.1101 +        PORT_Memset(&sid, 0, sizeof(sslSessionID));
  1.1102 +
  1.1103 +        if (ss->ssl3.hs.kea_def->kea == kea_ecdhe_rsa) {
  1.1104 +            effectiveExchKeyType = kt_rsa;
  1.1105 +        } else {
  1.1106 +            effectiveExchKeyType = ss->ssl3.hs.kea_def->exchKeyType;
  1.1107 +        }
  1.1108 +
  1.1109 +        rv = ssl3_CacheWrappedMasterSecret(ss, &sid, ss->ssl3.pwSpec,
  1.1110 +            effectiveExchKeyType);
  1.1111 +        if (rv == SECSuccess) {
  1.1112 +            if (sid.u.ssl3.keys.wrapped_master_secret_len > sizeof(wrapped_ms))
  1.1113 +                goto loser;
  1.1114 +            memcpy(wrapped_ms, sid.u.ssl3.keys.wrapped_master_secret,
  1.1115 +                sid.u.ssl3.keys.wrapped_master_secret_len);
  1.1116 +            ms_item.data = wrapped_ms;
  1.1117 +            ms_item.len = sid.u.ssl3.keys.wrapped_master_secret_len;
  1.1118 +            msWrapMech = sid.u.ssl3.masterWrapMech;
  1.1119 +        } else {
  1.1120 +            /* TODO: else send an empty ticket. */
  1.1121 +            goto loser;
  1.1122 +        }
  1.1123 +        ms_is_wrapped = PR_TRUE;
  1.1124 +    }
  1.1125 +    /* Prep to send negotiated name */
  1.1126 +    srvName = &ss->ssl3.pwSpec->srvVirtName;
  1.1127 +    if (srvName->data && srvName->len) {
  1.1128 +        srvNameLen = 2 + srvName->len; /* len bytes + name len */
  1.1129 +    }
  1.1130 +
  1.1131 +    ciphertext_length =
  1.1132 +        sizeof(PRUint16)                     /* ticket_version */
  1.1133 +        + sizeof(SSL3ProtocolVersion)        /* ssl_version */
  1.1134 +        + sizeof(ssl3CipherSuite)            /* ciphersuite */
  1.1135 +        + 1                                  /* compression */
  1.1136 +        + 10                                 /* cipher spec parameters */
  1.1137 +        + 1                                  /* SessionTicket.ms_is_wrapped */
  1.1138 +        + 1                                  /* effectiveExchKeyType */
  1.1139 +        + 4                                  /* msWrapMech */
  1.1140 +        + 2                                  /* master_secret.length */
  1.1141 +        + ms_item.len                        /* master_secret */
  1.1142 +        + 1                                  /* client_auth_type */
  1.1143 +        + cert_length                        /* cert */
  1.1144 +        + 1                                  /* server name type */
  1.1145 +        + srvNameLen                         /* name len + length field */
  1.1146 +        + sizeof(ticket.ticket_lifetime_hint);
  1.1147 +    padding_length =  AES_BLOCK_SIZE -
  1.1148 +        (ciphertext_length % AES_BLOCK_SIZE);
  1.1149 +    ciphertext_length += padding_length;
  1.1150 +
  1.1151 +    message_length =
  1.1152 +        sizeof(ticket.ticket_lifetime_hint)    /* ticket_lifetime_hint */
  1.1153 +        + 2 /* length field for NewSessionTicket.ticket */
  1.1154 +        + SESS_TICKET_KEY_NAME_LEN             /* key_name */
  1.1155 +        + AES_BLOCK_SIZE                       /* iv */
  1.1156 +        + 2 /* length field for NewSessionTicket.ticket.encrypted_state */
  1.1157 +        + ciphertext_length                    /* encrypted_state */
  1.1158 +        + TLS_EX_SESS_TICKET_MAC_LENGTH;       /* mac */
  1.1159 +
  1.1160 +    if (SECITEM_AllocItem(NULL, &plaintext_item, ciphertext_length) == NULL)
  1.1161 +        goto loser;
  1.1162 +
  1.1163 +    plaintext = plaintext_item;
  1.1164 +
  1.1165 +    /* ticket_version */
  1.1166 +    rv = ssl3_AppendNumberToItem(&plaintext, TLS_EX_SESS_TICKET_VERSION,
  1.1167 +        sizeof(PRUint16));
  1.1168 +    if (rv != SECSuccess) goto loser;
  1.1169 +
  1.1170 +    /* ssl_version */
  1.1171 +    rv = ssl3_AppendNumberToItem(&plaintext, ss->version,
  1.1172 +        sizeof(SSL3ProtocolVersion));
  1.1173 +    if (rv != SECSuccess) goto loser;
  1.1174 +
  1.1175 +    /* ciphersuite */
  1.1176 +    rv = ssl3_AppendNumberToItem(&plaintext, ss->ssl3.hs.cipher_suite,
  1.1177 +        sizeof(ssl3CipherSuite));
  1.1178 +    if (rv != SECSuccess) goto loser;
  1.1179 +
  1.1180 +    /* compression */
  1.1181 +    rv = ssl3_AppendNumberToItem(&plaintext, ss->ssl3.hs.compression, 1);
  1.1182 +    if (rv != SECSuccess) goto loser;
  1.1183 +
  1.1184 +    /* cipher spec parameters */
  1.1185 +    rv = ssl3_AppendNumberToItem(&plaintext, ss->sec.authAlgorithm, 1);
  1.1186 +    if (rv != SECSuccess) goto loser;
  1.1187 +    rv = ssl3_AppendNumberToItem(&plaintext, ss->sec.authKeyBits, 4);
  1.1188 +    if (rv != SECSuccess) goto loser;
  1.1189 +    rv = ssl3_AppendNumberToItem(&plaintext, ss->sec.keaType, 1);
  1.1190 +    if (rv != SECSuccess) goto loser;
  1.1191 +    rv = ssl3_AppendNumberToItem(&plaintext, ss->sec.keaKeyBits, 4);
  1.1192 +    if (rv != SECSuccess) goto loser;
  1.1193 +
  1.1194 +    /* master_secret */
  1.1195 +    rv = ssl3_AppendNumberToItem(&plaintext, ms_is_wrapped, 1);
  1.1196 +    if (rv != SECSuccess) goto loser;
  1.1197 +    rv = ssl3_AppendNumberToItem(&plaintext, effectiveExchKeyType, 1);
  1.1198 +    if (rv != SECSuccess) goto loser;
  1.1199 +    rv = ssl3_AppendNumberToItem(&plaintext, msWrapMech, 4);
  1.1200 +    if (rv != SECSuccess) goto loser;
  1.1201 +    rv = ssl3_AppendNumberToItem(&plaintext, ms_item.len, 2);
  1.1202 +    if (rv != SECSuccess) goto loser;
  1.1203 +    rv = ssl3_AppendToItem(&plaintext, ms_item.data, ms_item.len);
  1.1204 +    if (rv != SECSuccess) goto loser;
  1.1205 +
  1.1206 +    /* client_identity */
  1.1207 +    if (ss->opt.requestCertificate && ss->sec.ci.sid->peerCert) {
  1.1208 +        rv = ssl3_AppendNumberToItem(&plaintext, CLIENT_AUTH_CERTIFICATE, 1);
  1.1209 +        if (rv != SECSuccess) goto loser;
  1.1210 +        rv = ssl3_AppendNumberToItem(&plaintext,
  1.1211 +            ss->sec.ci.sid->peerCert->derCert.len, 3);
  1.1212 +        if (rv != SECSuccess) goto loser;
  1.1213 +        rv = ssl3_AppendToItem(&plaintext,
  1.1214 +            ss->sec.ci.sid->peerCert->derCert.data,
  1.1215 +            ss->sec.ci.sid->peerCert->derCert.len);
  1.1216 +        if (rv != SECSuccess) goto loser;
  1.1217 +    } else {
  1.1218 +        rv = ssl3_AppendNumberToItem(&plaintext, 0, 1);
  1.1219 +        if (rv != SECSuccess) goto loser;
  1.1220 +    }
  1.1221 +
  1.1222 +    /* timestamp */
  1.1223 +    now = ssl_Time();
  1.1224 +    rv = ssl3_AppendNumberToItem(&plaintext, now,
  1.1225 +        sizeof(ticket.ticket_lifetime_hint));
  1.1226 +    if (rv != SECSuccess) goto loser;
  1.1227 +
  1.1228 +    if (srvNameLen) {
  1.1229 +        /* Name Type (sni_host_name) */
  1.1230 +        rv = ssl3_AppendNumberToItem(&plaintext, srvName->type, 1);
  1.1231 +        if (rv != SECSuccess) goto loser;
  1.1232 +        /* HostName (length and value) */
  1.1233 +        rv = ssl3_AppendNumberToItem(&plaintext, srvName->len, 2);
  1.1234 +        if (rv != SECSuccess) goto loser;
  1.1235 +        rv = ssl3_AppendToItem(&plaintext, srvName->data, srvName->len);
  1.1236 +        if (rv != SECSuccess) goto loser;
  1.1237 +    } else {
  1.1238 +        /* No Name */
  1.1239 +        rv = ssl3_AppendNumberToItem(&plaintext, (char)TLS_STE_NO_SERVER_NAME,
  1.1240 +                                     1);
  1.1241 +        if (rv != SECSuccess) goto loser;
  1.1242 +    }
  1.1243 +
  1.1244 +    PORT_Assert(plaintext.len == padding_length);
  1.1245 +    for (i = 0; i < padding_length; i++)
  1.1246 +        plaintext.data[i] = (unsigned char)padding_length;
  1.1247 +
  1.1248 +    if (SECITEM_AllocItem(NULL, &ciphertext, ciphertext_length) == NULL) {
  1.1249 +        rv = SECFailure;
  1.1250 +        goto loser;
  1.1251 +    }
  1.1252 +
  1.1253 +    /* Generate encrypted portion of ticket. */
  1.1254 +#ifndef NO_PKCS11_BYPASS
  1.1255 +    if (ss->opt.bypassPKCS11) {
  1.1256 +        aes_ctx = (AESContext *)aes_ctx_buf;
  1.1257 +        rv = AES_InitContext(aes_ctx, aes_key, aes_key_length, iv,
  1.1258 +            NSS_AES_CBC, 1, AES_BLOCK_SIZE);
  1.1259 +        if (rv != SECSuccess) goto loser;
  1.1260 +
  1.1261 +        rv = AES_Encrypt(aes_ctx, ciphertext.data, &ciphertext.len,
  1.1262 +            ciphertext.len, plaintext_item.data,
  1.1263 +            plaintext_item.len);
  1.1264 +        if (rv != SECSuccess) goto loser;
  1.1265 +    } else
  1.1266 +#endif
  1.1267 +    {
  1.1268 +        aes_ctx_pkcs11 = PK11_CreateContextBySymKey(cipherMech,
  1.1269 +            CKA_ENCRYPT, aes_key_pkcs11, &ivItem);
  1.1270 +        if (!aes_ctx_pkcs11)
  1.1271 +            goto loser;
  1.1272 +
  1.1273 +        rv = PK11_CipherOp(aes_ctx_pkcs11, ciphertext.data,
  1.1274 +            (int *)&ciphertext.len, ciphertext.len,
  1.1275 +            plaintext_item.data, plaintext_item.len);
  1.1276 +        PK11_Finalize(aes_ctx_pkcs11);
  1.1277 +        PK11_DestroyContext(aes_ctx_pkcs11, PR_TRUE);
  1.1278 +        if (rv != SECSuccess) goto loser;
  1.1279 +    }
  1.1280 +
  1.1281 +    /* Convert ciphertext length to network order. */
  1.1282 +    length_buf[0] = (ciphertext.len >> 8) & 0xff;
  1.1283 +    length_buf[1] = (ciphertext.len     ) & 0xff;
  1.1284 +
  1.1285 +    /* Compute MAC. */
  1.1286 +#ifndef NO_PKCS11_BYPASS
  1.1287 +    if (ss->opt.bypassPKCS11) {
  1.1288 +        hmac_ctx = (HMACContext *)hmac_ctx_buf;
  1.1289 +        hashObj = HASH_GetRawHashObject(HASH_AlgSHA256);
  1.1290 +        if (HMAC_Init(hmac_ctx, hashObj, mac_key,
  1.1291 +                mac_key_length, PR_FALSE) != SECSuccess)
  1.1292 +            goto loser;
  1.1293 +
  1.1294 +        HMAC_Begin(hmac_ctx);
  1.1295 +        HMAC_Update(hmac_ctx, key_name, SESS_TICKET_KEY_NAME_LEN);
  1.1296 +        HMAC_Update(hmac_ctx, iv, sizeof(iv));
  1.1297 +        HMAC_Update(hmac_ctx, (unsigned char *)length_buf, 2);
  1.1298 +        HMAC_Update(hmac_ctx, ciphertext.data, ciphertext.len);
  1.1299 +        HMAC_Finish(hmac_ctx, computed_mac, &computed_mac_length,
  1.1300 +            sizeof(computed_mac));
  1.1301 +    } else
  1.1302 +#endif
  1.1303 +    {
  1.1304 +        SECItem macParam;
  1.1305 +        macParam.data = NULL;
  1.1306 +        macParam.len = 0;
  1.1307 +        hmac_ctx_pkcs11 = PK11_CreateContextBySymKey(macMech,
  1.1308 +            CKA_SIGN, mac_key_pkcs11, &macParam);
  1.1309 +        if (!hmac_ctx_pkcs11)
  1.1310 +            goto loser;
  1.1311 +
  1.1312 +        rv = PK11_DigestBegin(hmac_ctx_pkcs11);
  1.1313 +        rv = PK11_DigestOp(hmac_ctx_pkcs11, key_name,
  1.1314 +            SESS_TICKET_KEY_NAME_LEN);
  1.1315 +        rv = PK11_DigestOp(hmac_ctx_pkcs11, iv, sizeof(iv));
  1.1316 +        rv = PK11_DigestOp(hmac_ctx_pkcs11, (unsigned char *)length_buf, 2);
  1.1317 +        rv = PK11_DigestOp(hmac_ctx_pkcs11, ciphertext.data, ciphertext.len);
  1.1318 +        rv = PK11_DigestFinal(hmac_ctx_pkcs11, computed_mac,
  1.1319 +            &computed_mac_length, sizeof(computed_mac));
  1.1320 +        PK11_DestroyContext(hmac_ctx_pkcs11, PR_TRUE);
  1.1321 +        if (rv != SECSuccess) goto loser;
  1.1322 +    }
  1.1323 +
  1.1324 +    /* Serialize the handshake message. */
  1.1325 +    rv = ssl3_AppendHandshakeHeader(ss, new_session_ticket, message_length);
  1.1326 +    if (rv != SECSuccess) goto loser;
  1.1327 +
  1.1328 +    rv = ssl3_AppendHandshakeNumber(ss, ticket.ticket_lifetime_hint,
  1.1329 +        sizeof(ticket.ticket_lifetime_hint));
  1.1330 +    if (rv != SECSuccess) goto loser;
  1.1331 +
  1.1332 +    rv = ssl3_AppendHandshakeNumber(ss,
  1.1333 +        message_length - sizeof(ticket.ticket_lifetime_hint) - 2, 2);
  1.1334 +    if (rv != SECSuccess) goto loser;
  1.1335 +
  1.1336 +    rv = ssl3_AppendHandshake(ss, key_name, SESS_TICKET_KEY_NAME_LEN);
  1.1337 +    if (rv != SECSuccess) goto loser;
  1.1338 +
  1.1339 +    rv = ssl3_AppendHandshake(ss, iv, sizeof(iv));
  1.1340 +    if (rv != SECSuccess) goto loser;
  1.1341 +
  1.1342 +    rv = ssl3_AppendHandshakeVariable(ss, ciphertext.data, ciphertext.len, 2);
  1.1343 +    if (rv != SECSuccess) goto loser;
  1.1344 +
  1.1345 +    rv = ssl3_AppendHandshake(ss, computed_mac, computed_mac_length);
  1.1346 +    if (rv != SECSuccess) goto loser;
  1.1347 +
  1.1348 +loser:
  1.1349 +    if (plaintext_item.data)
  1.1350 +        SECITEM_FreeItem(&plaintext_item, PR_FALSE);
  1.1351 +    if (ciphertext.data)
  1.1352 +        SECITEM_FreeItem(&ciphertext, PR_FALSE);
  1.1353 +
  1.1354 +    return rv;
  1.1355 +}
  1.1356 +
  1.1357 +/* When a client receives a SessionTicket extension a NewSessionTicket
  1.1358 + * message is expected during the handshake.
  1.1359 + */
  1.1360 +SECStatus
  1.1361 +ssl3_ClientHandleSessionTicketXtn(sslSocket *ss, PRUint16 ex_type,
  1.1362 +                                  SECItem *data)
  1.1363 +{
  1.1364 +    if (data->len != 0)
  1.1365 +        return SECFailure;
  1.1366 +
  1.1367 +    /* Keep track of negotiated extensions. */
  1.1368 +    ss->xtnData.negotiated[ss->xtnData.numNegotiated++] = ex_type;
  1.1369 +    return SECSuccess;
  1.1370 +}
  1.1371 +
  1.1372 +SECStatus
  1.1373 +ssl3_ServerHandleSessionTicketXtn(sslSocket *ss, PRUint16 ex_type,
  1.1374 +                                  SECItem *data)
  1.1375 +{
  1.1376 +    SECStatus rv;
  1.1377 +    SECItem *decrypted_state = NULL;
  1.1378 +    SessionTicket *parsed_session_ticket = NULL;
  1.1379 +    sslSessionID *sid = NULL;
  1.1380 +    SSL3Statistics *ssl3stats;
  1.1381 +
  1.1382 +    /* Ignore the SessionTicket extension if processing is disabled. */
  1.1383 +    if (!ss->opt.enableSessionTickets)
  1.1384 +        return SECSuccess;
  1.1385 +
  1.1386 +    /* Keep track of negotiated extensions. */
  1.1387 +    ss->xtnData.negotiated[ss->xtnData.numNegotiated++] = ex_type;
  1.1388 +
  1.1389 +    /* Parse the received ticket sent in by the client.  We are
  1.1390 +     * lenient about some parse errors, falling back to a fullshake
  1.1391 +     * instead of terminating the current connection.
  1.1392 +     */
  1.1393 +    if (data->len == 0) {
  1.1394 +        ss->xtnData.emptySessionTicket = PR_TRUE;
  1.1395 +    } else {
  1.1396 +        int                    i;
  1.1397 +        SECItem                extension_data;
  1.1398 +        EncryptedSessionTicket enc_session_ticket;
  1.1399 +        unsigned char          computed_mac[TLS_EX_SESS_TICKET_MAC_LENGTH];
  1.1400 +        unsigned int           computed_mac_length;
  1.1401 +#ifndef NO_PKCS11_BYPASS
  1.1402 +        const SECHashObject   *hashObj;
  1.1403 +        const unsigned char   *aes_key;
  1.1404 +        const unsigned char   *mac_key;
  1.1405 +        PRUint32               aes_key_length;
  1.1406 +        PRUint32               mac_key_length;
  1.1407 +        PRUint64               hmac_ctx_buf[MAX_MAC_CONTEXT_LLONGS];
  1.1408 +        HMACContext           *hmac_ctx;
  1.1409 +        PRUint64               aes_ctx_buf[MAX_CIPHER_CONTEXT_LLONGS];
  1.1410 +        AESContext            *aes_ctx;
  1.1411 +#endif
  1.1412 +        PK11SymKey            *aes_key_pkcs11;
  1.1413 +        PK11SymKey            *mac_key_pkcs11;
  1.1414 +        PK11Context           *hmac_ctx_pkcs11;
  1.1415 +        CK_MECHANISM_TYPE      macMech = CKM_SHA256_HMAC;
  1.1416 +        PK11Context           *aes_ctx_pkcs11;
  1.1417 +        CK_MECHANISM_TYPE      cipherMech = CKM_AES_CBC;
  1.1418 +        unsigned char *        padding;
  1.1419 +        PRUint32               padding_length;
  1.1420 +        unsigned char         *buffer;
  1.1421 +        unsigned int           buffer_len;
  1.1422 +        PRInt32                temp;
  1.1423 +        SECItem                cert_item;
  1.1424 +        PRInt8                 nameType = TLS_STE_NO_SERVER_NAME;
  1.1425 +
  1.1426 +        /* Turn off stateless session resumption if the client sends a
  1.1427 +         * SessionTicket extension, even if the extension turns out to be
  1.1428 +         * malformed (ss->sec.ci.sid is non-NULL when doing session
  1.1429 +         * renegotiation.)
  1.1430 +         */
  1.1431 +        if (ss->sec.ci.sid != NULL) {
  1.1432 +            if (ss->sec.uncache)
  1.1433 +                ss->sec.uncache(ss->sec.ci.sid);
  1.1434 +            ssl_FreeSID(ss->sec.ci.sid);
  1.1435 +            ss->sec.ci.sid = NULL;
  1.1436 +        }
  1.1437 +
  1.1438 +        extension_data.data = data->data; /* Keep a copy for future use. */
  1.1439 +        extension_data.len = data->len;
  1.1440 +
  1.1441 +        if (ssl3_ParseEncryptedSessionTicket(ss, data, &enc_session_ticket)
  1.1442 +            != SECSuccess)
  1.1443 +            return SECFailure;
  1.1444 +
  1.1445 +        /* Get session ticket keys. */
  1.1446 +#ifndef NO_PKCS11_BYPASS
  1.1447 +        if (ss->opt.bypassPKCS11) {
  1.1448 +            rv = ssl3_GetSessionTicketKeys(&aes_key, &aes_key_length,
  1.1449 +                &mac_key, &mac_key_length);
  1.1450 +        } else
  1.1451 +#endif
  1.1452 +        {
  1.1453 +            rv = ssl3_GetSessionTicketKeysPKCS11(ss, &aes_key_pkcs11,
  1.1454 +                &mac_key_pkcs11);
  1.1455 +        }
  1.1456 +        if (rv != SECSuccess) {
  1.1457 +            SSL_DBG(("%d: SSL[%d]: Unable to get/generate session ticket keys.",
  1.1458 +                        SSL_GETPID(), ss->fd));
  1.1459 +            goto loser;
  1.1460 +        }
  1.1461 +
  1.1462 +        /* If the ticket sent by the client was generated under a key different
  1.1463 +         * from the one we have, bypass ticket processing.
  1.1464 +         */
  1.1465 +        if (PORT_Memcmp(enc_session_ticket.key_name, key_name,
  1.1466 +                SESS_TICKET_KEY_NAME_LEN) != 0) {
  1.1467 +            SSL_DBG(("%d: SSL[%d]: Session ticket key_name sent mismatch.",
  1.1468 +                        SSL_GETPID(), ss->fd));
  1.1469 +            goto no_ticket;
  1.1470 +        }
  1.1471 +
  1.1472 +        /* Verify the MAC on the ticket.  MAC verification may also
  1.1473 +         * fail if the MAC key has been recently refreshed.
  1.1474 +         */
  1.1475 +#ifndef NO_PKCS11_BYPASS
  1.1476 +        if (ss->opt.bypassPKCS11) {
  1.1477 +            hmac_ctx = (HMACContext *)hmac_ctx_buf;
  1.1478 +            hashObj = HASH_GetRawHashObject(HASH_AlgSHA256);
  1.1479 +            if (HMAC_Init(hmac_ctx, hashObj, mac_key,
  1.1480 +                    sizeof(session_ticket_mac_key), PR_FALSE) != SECSuccess)
  1.1481 +                goto no_ticket;
  1.1482 +            HMAC_Begin(hmac_ctx);
  1.1483 +            HMAC_Update(hmac_ctx, extension_data.data,
  1.1484 +                extension_data.len - TLS_EX_SESS_TICKET_MAC_LENGTH);
  1.1485 +            if (HMAC_Finish(hmac_ctx, computed_mac, &computed_mac_length,
  1.1486 +                    sizeof(computed_mac)) != SECSuccess)
  1.1487 +                goto no_ticket;
  1.1488 +        } else
  1.1489 +#endif
  1.1490 +        {
  1.1491 +            SECItem macParam;
  1.1492 +            macParam.data = NULL;
  1.1493 +            macParam.len = 0;
  1.1494 +            hmac_ctx_pkcs11 = PK11_CreateContextBySymKey(macMech,
  1.1495 +                CKA_SIGN, mac_key_pkcs11, &macParam);
  1.1496 +            if (!hmac_ctx_pkcs11) {
  1.1497 +                SSL_DBG(("%d: SSL[%d]: Unable to create HMAC context: %d.",
  1.1498 +                            SSL_GETPID(), ss->fd, PORT_GetError()));
  1.1499 +                goto no_ticket;
  1.1500 +            } else {
  1.1501 +                SSL_DBG(("%d: SSL[%d]: Successfully created HMAC context.",
  1.1502 +                            SSL_GETPID(), ss->fd));
  1.1503 +            }
  1.1504 +            rv = PK11_DigestBegin(hmac_ctx_pkcs11);
  1.1505 +            rv = PK11_DigestOp(hmac_ctx_pkcs11, extension_data.data,
  1.1506 +                extension_data.len - TLS_EX_SESS_TICKET_MAC_LENGTH);
  1.1507 +            if (rv != SECSuccess) {
  1.1508 +                PK11_DestroyContext(hmac_ctx_pkcs11, PR_TRUE);
  1.1509 +                goto no_ticket;
  1.1510 +            }
  1.1511 +            rv = PK11_DigestFinal(hmac_ctx_pkcs11, computed_mac,
  1.1512 +                &computed_mac_length, sizeof(computed_mac));
  1.1513 +            PK11_DestroyContext(hmac_ctx_pkcs11, PR_TRUE);
  1.1514 +            if (rv != SECSuccess)
  1.1515 +                goto no_ticket;
  1.1516 +        }
  1.1517 +        if (NSS_SecureMemcmp(computed_mac, enc_session_ticket.mac,
  1.1518 +                computed_mac_length) != 0) {
  1.1519 +            SSL_DBG(("%d: SSL[%d]: Session ticket MAC mismatch.",
  1.1520 +                        SSL_GETPID(), ss->fd));
  1.1521 +            goto no_ticket;
  1.1522 +        }
  1.1523 +
  1.1524 +        /* We ignore key_name for now.
  1.1525 +         * This is ok as MAC verification succeeded.
  1.1526 +         */
  1.1527 +
  1.1528 +        /* Decrypt the ticket. */
  1.1529 +
  1.1530 +        /* Plaintext is shorter than the ciphertext due to padding. */
  1.1531 +        decrypted_state = SECITEM_AllocItem(NULL, NULL,
  1.1532 +            enc_session_ticket.encrypted_state.len);
  1.1533 +
  1.1534 +#ifndef NO_PKCS11_BYPASS
  1.1535 +        if (ss->opt.bypassPKCS11) {
  1.1536 +            aes_ctx = (AESContext *)aes_ctx_buf;
  1.1537 +            rv = AES_InitContext(aes_ctx, aes_key,
  1.1538 +                sizeof(session_ticket_enc_key), enc_session_ticket.iv,
  1.1539 +                NSS_AES_CBC, 0,AES_BLOCK_SIZE);
  1.1540 +            if (rv != SECSuccess) {
  1.1541 +                SSL_DBG(("%d: SSL[%d]: Unable to create AES context.",
  1.1542 +                            SSL_GETPID(), ss->fd));
  1.1543 +                goto no_ticket;
  1.1544 +            }
  1.1545 +
  1.1546 +            rv = AES_Decrypt(aes_ctx, decrypted_state->data,
  1.1547 +                &decrypted_state->len, decrypted_state->len,
  1.1548 +                enc_session_ticket.encrypted_state.data,
  1.1549 +                enc_session_ticket.encrypted_state.len);
  1.1550 +            if (rv != SECSuccess)
  1.1551 +                goto no_ticket;
  1.1552 +        } else
  1.1553 +#endif
  1.1554 +        {
  1.1555 +            SECItem ivItem;
  1.1556 +            ivItem.data = enc_session_ticket.iv;
  1.1557 +            ivItem.len = AES_BLOCK_SIZE;
  1.1558 +            aes_ctx_pkcs11 = PK11_CreateContextBySymKey(cipherMech,
  1.1559 +                CKA_DECRYPT, aes_key_pkcs11, &ivItem);
  1.1560 +            if (!aes_ctx_pkcs11) {
  1.1561 +                SSL_DBG(("%d: SSL[%d]: Unable to create AES context.",
  1.1562 +                            SSL_GETPID(), ss->fd));
  1.1563 +                goto no_ticket;
  1.1564 +            }
  1.1565 +
  1.1566 +            rv = PK11_CipherOp(aes_ctx_pkcs11, decrypted_state->data,
  1.1567 +                (int *)&decrypted_state->len, decrypted_state->len,
  1.1568 +                enc_session_ticket.encrypted_state.data,
  1.1569 +                enc_session_ticket.encrypted_state.len);
  1.1570 +            PK11_Finalize(aes_ctx_pkcs11);
  1.1571 +            PK11_DestroyContext(aes_ctx_pkcs11, PR_TRUE);
  1.1572 +            if (rv != SECSuccess)
  1.1573 +                goto no_ticket;
  1.1574 +        }
  1.1575 +
  1.1576 +        /* Check padding. */
  1.1577 +        padding_length =
  1.1578 +            (PRUint32)decrypted_state->data[decrypted_state->len - 1];
  1.1579 +        if (padding_length == 0 || padding_length > AES_BLOCK_SIZE)
  1.1580 +            goto no_ticket;
  1.1581 +
  1.1582 +        padding = &decrypted_state->data[decrypted_state->len - padding_length];
  1.1583 +        for (i = 0; i < padding_length; i++, padding++) {
  1.1584 +            if (padding_length != (PRUint32)*padding)
  1.1585 +                goto no_ticket;
  1.1586 +        }
  1.1587 +
  1.1588 +        /* Deserialize session state. */
  1.1589 +        buffer = decrypted_state->data;
  1.1590 +        buffer_len = decrypted_state->len;
  1.1591 +
  1.1592 +        parsed_session_ticket = PORT_ZAlloc(sizeof(SessionTicket));
  1.1593 +        if (parsed_session_ticket == NULL) {
  1.1594 +            rv = SECFailure;
  1.1595 +            goto loser;
  1.1596 +        }
  1.1597 +
  1.1598 +        /* Read ticket_version (which is ignored for now.) */
  1.1599 +        temp = ssl3_ConsumeHandshakeNumber(ss, 2, &buffer, &buffer_len);
  1.1600 +        if (temp < 0) goto no_ticket;
  1.1601 +        parsed_session_ticket->ticket_version = (SSL3ProtocolVersion)temp;
  1.1602 +
  1.1603 +        /* Read SSLVersion. */
  1.1604 +        temp = ssl3_ConsumeHandshakeNumber(ss, 2, &buffer, &buffer_len);
  1.1605 +        if (temp < 0) goto no_ticket;
  1.1606 +        parsed_session_ticket->ssl_version = (SSL3ProtocolVersion)temp;
  1.1607 +
  1.1608 +        /* Read cipher_suite. */
  1.1609 +        temp =  ssl3_ConsumeHandshakeNumber(ss, 2, &buffer, &buffer_len);
  1.1610 +        if (temp < 0) goto no_ticket;
  1.1611 +        parsed_session_ticket->cipher_suite = (ssl3CipherSuite)temp;
  1.1612 +
  1.1613 +        /* Read compression_method. */
  1.1614 +        temp = ssl3_ConsumeHandshakeNumber(ss, 1, &buffer, &buffer_len);
  1.1615 +        if (temp < 0) goto no_ticket;
  1.1616 +        parsed_session_ticket->compression_method = (SSLCompressionMethod)temp;
  1.1617 +
  1.1618 +        /* Read cipher spec parameters. */
  1.1619 +        temp = ssl3_ConsumeHandshakeNumber(ss, 1, &buffer, &buffer_len);
  1.1620 +        if (temp < 0) goto no_ticket;
  1.1621 +        parsed_session_ticket->authAlgorithm = (SSLSignType)temp;
  1.1622 +        temp = ssl3_ConsumeHandshakeNumber(ss, 4, &buffer, &buffer_len);
  1.1623 +        if (temp < 0) goto no_ticket;
  1.1624 +        parsed_session_ticket->authKeyBits = (PRUint32)temp;
  1.1625 +        temp = ssl3_ConsumeHandshakeNumber(ss, 1, &buffer, &buffer_len);
  1.1626 +        if (temp < 0) goto no_ticket;
  1.1627 +        parsed_session_ticket->keaType = (SSLKEAType)temp;
  1.1628 +        temp = ssl3_ConsumeHandshakeNumber(ss, 4, &buffer, &buffer_len);
  1.1629 +        if (temp < 0) goto no_ticket;
  1.1630 +        parsed_session_ticket->keaKeyBits = (PRUint32)temp;
  1.1631 +
  1.1632 +        /* Read wrapped master_secret. */
  1.1633 +        temp = ssl3_ConsumeHandshakeNumber(ss, 1, &buffer, &buffer_len);
  1.1634 +        if (temp < 0) goto no_ticket;
  1.1635 +        parsed_session_ticket->ms_is_wrapped = (PRBool)temp;
  1.1636 +
  1.1637 +        temp = ssl3_ConsumeHandshakeNumber(ss, 1, &buffer, &buffer_len);
  1.1638 +        if (temp < 0) goto no_ticket;
  1.1639 +        parsed_session_ticket->exchKeyType = (SSL3KEAType)temp;
  1.1640 +
  1.1641 +        temp = ssl3_ConsumeHandshakeNumber(ss, 4, &buffer, &buffer_len);
  1.1642 +        if (temp < 0) goto no_ticket;
  1.1643 +        parsed_session_ticket->msWrapMech = (CK_MECHANISM_TYPE)temp;
  1.1644 +
  1.1645 +        temp = ssl3_ConsumeHandshakeNumber(ss, 2, &buffer, &buffer_len);
  1.1646 +        if (temp < 0) goto no_ticket;
  1.1647 +        parsed_session_ticket->ms_length = (PRUint16)temp;
  1.1648 +        if (parsed_session_ticket->ms_length == 0 ||  /* sanity check MS. */
  1.1649 +            parsed_session_ticket->ms_length >
  1.1650 +            sizeof(parsed_session_ticket->master_secret))
  1.1651 +            goto no_ticket;
  1.1652 +
  1.1653 +        /* Allow for the wrapped master secret to be longer. */
  1.1654 +        if (buffer_len < parsed_session_ticket->ms_length)
  1.1655 +            goto no_ticket;
  1.1656 +        PORT_Memcpy(parsed_session_ticket->master_secret, buffer,
  1.1657 +            parsed_session_ticket->ms_length);
  1.1658 +        buffer += parsed_session_ticket->ms_length;
  1.1659 +        buffer_len -= parsed_session_ticket->ms_length;
  1.1660 +
  1.1661 +        /* Read client_identity */
  1.1662 +        temp = ssl3_ConsumeHandshakeNumber(ss, 1, &buffer, &buffer_len);
  1.1663 +        if (temp < 0)
  1.1664 +            goto no_ticket;
  1.1665 +        parsed_session_ticket->client_identity.client_auth_type =
  1.1666 +            (ClientAuthenticationType)temp;
  1.1667 +        switch(parsed_session_ticket->client_identity.client_auth_type) {
  1.1668 +            case CLIENT_AUTH_ANONYMOUS:
  1.1669 +                break;
  1.1670 +            case CLIENT_AUTH_CERTIFICATE:
  1.1671 +                rv = ssl3_ConsumeHandshakeVariable(ss, &cert_item, 3,
  1.1672 +                    &buffer, &buffer_len);
  1.1673 +                if (rv != SECSuccess) goto no_ticket;
  1.1674 +                rv = SECITEM_CopyItem(NULL, &parsed_session_ticket->peer_cert,
  1.1675 +                    &cert_item);
  1.1676 +                if (rv != SECSuccess) goto no_ticket;
  1.1677 +                break;
  1.1678 +            default:
  1.1679 +                goto no_ticket;
  1.1680 +        }
  1.1681 +        /* Read timestamp. */
  1.1682 +        temp = ssl3_ConsumeHandshakeNumber(ss, 4, &buffer, &buffer_len);
  1.1683 +        if (temp < 0)
  1.1684 +            goto no_ticket;
  1.1685 +        parsed_session_ticket->timestamp = (PRUint32)temp;
  1.1686 +
  1.1687 +        /* Read server name */
  1.1688 +        nameType =
  1.1689 +                ssl3_ConsumeHandshakeNumber(ss, 1, &buffer, &buffer_len);
  1.1690 +        if (nameType != TLS_STE_NO_SERVER_NAME) {
  1.1691 +            SECItem name_item;
  1.1692 +            rv = ssl3_ConsumeHandshakeVariable(ss, &name_item, 2, &buffer,
  1.1693 +                                               &buffer_len);
  1.1694 +            if (rv != SECSuccess) goto no_ticket;
  1.1695 +            rv = SECITEM_CopyItem(NULL, &parsed_session_ticket->srvName,
  1.1696 +                                  &name_item);
  1.1697 +            if (rv != SECSuccess) goto no_ticket;
  1.1698 +            parsed_session_ticket->srvName.type = nameType;
  1.1699 +        }
  1.1700 +
  1.1701 +        /* Done parsing.  Check that all bytes have been consumed. */
  1.1702 +        if (buffer_len != padding_length)
  1.1703 +            goto no_ticket;
  1.1704 +
  1.1705 +        /* Use the ticket if it has not expired, otherwise free the allocated
  1.1706 +         * memory since the ticket is of no use.
  1.1707 +         */
  1.1708 +        if (parsed_session_ticket->timestamp != 0 &&
  1.1709 +            parsed_session_ticket->timestamp +
  1.1710 +            TLS_EX_SESS_TICKET_LIFETIME_HINT > ssl_Time()) {
  1.1711 +
  1.1712 +            sid = ssl3_NewSessionID(ss, PR_TRUE);
  1.1713 +            if (sid == NULL) {
  1.1714 +                rv = SECFailure;
  1.1715 +                goto loser;
  1.1716 +            }
  1.1717 +
  1.1718 +            /* Copy over parameters. */
  1.1719 +            sid->version = parsed_session_ticket->ssl_version;
  1.1720 +            sid->u.ssl3.cipherSuite = parsed_session_ticket->cipher_suite;
  1.1721 +            sid->u.ssl3.compression = parsed_session_ticket->compression_method;
  1.1722 +            sid->authAlgorithm = parsed_session_ticket->authAlgorithm;
  1.1723 +            sid->authKeyBits = parsed_session_ticket->authKeyBits;
  1.1724 +            sid->keaType = parsed_session_ticket->keaType;
  1.1725 +            sid->keaKeyBits = parsed_session_ticket->keaKeyBits;
  1.1726 +
  1.1727 +            /* Copy master secret. */
  1.1728 +#ifndef NO_PKCS11_BYPASS
  1.1729 +            if (ss->opt.bypassPKCS11 &&
  1.1730 +                    parsed_session_ticket->ms_is_wrapped)
  1.1731 +                goto no_ticket;
  1.1732 +#endif
  1.1733 +            if (parsed_session_ticket->ms_length >
  1.1734 +                    sizeof(sid->u.ssl3.keys.wrapped_master_secret))
  1.1735 +                goto no_ticket;
  1.1736 +            PORT_Memcpy(sid->u.ssl3.keys.wrapped_master_secret,
  1.1737 +                parsed_session_ticket->master_secret,
  1.1738 +                parsed_session_ticket->ms_length);
  1.1739 +            sid->u.ssl3.keys.wrapped_master_secret_len =
  1.1740 +                parsed_session_ticket->ms_length;
  1.1741 +            sid->u.ssl3.exchKeyType = parsed_session_ticket->exchKeyType;
  1.1742 +            sid->u.ssl3.masterWrapMech = parsed_session_ticket->msWrapMech;
  1.1743 +            sid->u.ssl3.keys.msIsWrapped =
  1.1744 +                parsed_session_ticket->ms_is_wrapped;
  1.1745 +            sid->u.ssl3.masterValid    = PR_TRUE;
  1.1746 +            sid->u.ssl3.keys.resumable = PR_TRUE;
  1.1747 +
  1.1748 +            /* Copy over client cert from session ticket if there is one. */
  1.1749 +            if (parsed_session_ticket->peer_cert.data != NULL) {
  1.1750 +                if (sid->peerCert != NULL)
  1.1751 +                    CERT_DestroyCertificate(sid->peerCert);
  1.1752 +                sid->peerCert = CERT_NewTempCertificate(ss->dbHandle,
  1.1753 +                    &parsed_session_ticket->peer_cert, NULL, PR_FALSE, PR_TRUE);
  1.1754 +                if (sid->peerCert == NULL) {
  1.1755 +                    rv = SECFailure;
  1.1756 +                    goto loser;
  1.1757 +                }
  1.1758 +            }
  1.1759 +            if (parsed_session_ticket->srvName.data != NULL) {
  1.1760 +                sid->u.ssl3.srvName = parsed_session_ticket->srvName;
  1.1761 +            }
  1.1762 +            ss->statelessResume = PR_TRUE;
  1.1763 +            ss->sec.ci.sid = sid;
  1.1764 +        }
  1.1765 +    }
  1.1766 +
  1.1767 +    if (0) {
  1.1768 +no_ticket:
  1.1769 +        SSL_DBG(("%d: SSL[%d]: Session ticket parsing failed.",
  1.1770 +                        SSL_GETPID(), ss->fd));
  1.1771 +        ssl3stats = SSL_GetStatistics();
  1.1772 +        SSL_AtomicIncrementLong(& ssl3stats->hch_sid_ticket_parse_failures );
  1.1773 +    }
  1.1774 +    rv = SECSuccess;
  1.1775 +
  1.1776 +loser:
  1.1777 +        /* ss->sec.ci.sid == sid if it did NOT come here via goto statement
  1.1778 +         * in that case do not free sid
  1.1779 +         */
  1.1780 +        if (sid && (ss->sec.ci.sid != sid)) {
  1.1781 +            ssl_FreeSID(sid);
  1.1782 +            sid = NULL;
  1.1783 +        }
  1.1784 +    if (decrypted_state != NULL) {
  1.1785 +        SECITEM_FreeItem(decrypted_state, PR_TRUE);
  1.1786 +        decrypted_state = NULL;
  1.1787 +    }
  1.1788 +
  1.1789 +    if (parsed_session_ticket != NULL) {
  1.1790 +        if (parsed_session_ticket->peer_cert.data) {
  1.1791 +            SECITEM_FreeItem(&parsed_session_ticket->peer_cert, PR_FALSE);
  1.1792 +        }
  1.1793 +        PORT_ZFree(parsed_session_ticket, sizeof(SessionTicket));
  1.1794 +    }
  1.1795 +
  1.1796 +    return rv;
  1.1797 +}
  1.1798 +
  1.1799 +/*
  1.1800 + * Read bytes.  Using this function means the SECItem structure
  1.1801 + * cannot be freed.  The caller is expected to call this function
  1.1802 + * on a shallow copy of the structure.
  1.1803 + */
  1.1804 +static SECStatus
  1.1805 +ssl3_ConsumeFromItem(SECItem *item, unsigned char **buf, PRUint32 bytes)
  1.1806 +{
  1.1807 +    if (bytes > item->len)
  1.1808 +        return SECFailure;
  1.1809 +
  1.1810 +    *buf = item->data;
  1.1811 +    item->data += bytes;
  1.1812 +    item->len -= bytes;
  1.1813 +    return SECSuccess;
  1.1814 +}
  1.1815 +
  1.1816 +static SECStatus
  1.1817 +ssl3_ParseEncryptedSessionTicket(sslSocket *ss, SECItem *data,
  1.1818 +                                 EncryptedSessionTicket *enc_session_ticket)
  1.1819 +{
  1.1820 +    if (ssl3_ConsumeFromItem(data, &enc_session_ticket->key_name,
  1.1821 +            SESS_TICKET_KEY_NAME_LEN) != SECSuccess)
  1.1822 +        return SECFailure;
  1.1823 +    if (ssl3_ConsumeFromItem(data, &enc_session_ticket->iv,
  1.1824 +            AES_BLOCK_SIZE) != SECSuccess)
  1.1825 +        return SECFailure;
  1.1826 +    if (ssl3_ConsumeHandshakeVariable(ss, &enc_session_ticket->encrypted_state,
  1.1827 +            2, &data->data, &data->len) != SECSuccess)
  1.1828 +        return SECFailure;
  1.1829 +    if (ssl3_ConsumeFromItem(data, &enc_session_ticket->mac,
  1.1830 +            TLS_EX_SESS_TICKET_MAC_LENGTH) != SECSuccess)
  1.1831 +        return SECFailure;
  1.1832 +    if (data->len != 0)  /* Make sure that we have consumed all bytes. */
  1.1833 +        return SECFailure;
  1.1834 +
  1.1835 +    return SECSuccess;
  1.1836 +}
  1.1837 +
  1.1838 +/* go through hello extensions in buffer "b".
  1.1839 + * For each one, find the extension handler in the table, and
  1.1840 + * if present, invoke that handler.
  1.1841 + * Servers ignore any extensions with unknown extension types.
  1.1842 + * Clients reject any extensions with unadvertised extension types.
  1.1843 + */
  1.1844 +SECStatus
  1.1845 +ssl3_HandleHelloExtensions(sslSocket *ss, SSL3Opaque **b, PRUint32 *length)
  1.1846 +{
  1.1847 +    const ssl3HelloExtensionHandler * handlers;
  1.1848 +
  1.1849 +    if (ss->sec.isServer) {
  1.1850 +        handlers = clientHelloHandlers;
  1.1851 +    } else if (ss->version > SSL_LIBRARY_VERSION_3_0) {
  1.1852 +        handlers = serverHelloHandlersTLS;
  1.1853 +    } else {
  1.1854 +        handlers = serverHelloHandlersSSL3;
  1.1855 +    }
  1.1856 +
  1.1857 +    while (*length) {
  1.1858 +        const ssl3HelloExtensionHandler * handler;
  1.1859 +        SECStatus rv;
  1.1860 +        PRInt32   extension_type;
  1.1861 +        SECItem   extension_data;
  1.1862 +
  1.1863 +        /* Get the extension's type field */
  1.1864 +        extension_type = ssl3_ConsumeHandshakeNumber(ss, 2, b, length);
  1.1865 +        if (extension_type < 0)  /* failure to decode extension_type */
  1.1866 +            return SECFailure;   /* alert already sent */
  1.1867 +
  1.1868 +        /* get the data for this extension, so we can pass it or skip it. */
  1.1869 +        rv = ssl3_ConsumeHandshakeVariable(ss, &extension_data, 2, b, length);
  1.1870 +        if (rv != SECSuccess)
  1.1871 +            return rv;
  1.1872 +
  1.1873 +        /* Check whether the server sent an extension which was not advertised
  1.1874 +         * in the ClientHello.
  1.1875 +         */
  1.1876 +        if (!ss->sec.isServer &&
  1.1877 +            !ssl3_ClientExtensionAdvertised(ss, extension_type))
  1.1878 +            return SECFailure;  /* TODO: send unsupported_extension alert */
  1.1879 +
  1.1880 +        /* Check whether an extension has been sent multiple times. */
  1.1881 +        if (ssl3_ExtensionNegotiated(ss, extension_type))
  1.1882 +            return SECFailure;
  1.1883 +
  1.1884 +        /* find extension_type in table of Hello Extension Handlers */
  1.1885 +        for (handler = handlers; handler->ex_type >= 0; handler++) {
  1.1886 +            /* if found, call this handler */
  1.1887 +            if (handler->ex_type == extension_type) {
  1.1888 +                rv = (*handler->ex_handler)(ss, (PRUint16)extension_type,
  1.1889 +                                                        &extension_data);
  1.1890 +                /* Ignore this result */
  1.1891 +                /* Treat all bad extensions as unrecognized types. */
  1.1892 +                break;
  1.1893 +            }
  1.1894 +        }
  1.1895 +    }
  1.1896 +    return SECSuccess;
  1.1897 +}
  1.1898 +
  1.1899 +/* Add a callback function to the table of senders of server hello extensions.
  1.1900 + */
  1.1901 +SECStatus
  1.1902 +ssl3_RegisterServerHelloExtensionSender(sslSocket *ss, PRUint16 ex_type,
  1.1903 +                                        ssl3HelloExtensionSenderFunc cb)
  1.1904 +{
  1.1905 +    int i;
  1.1906 +    ssl3HelloExtensionSender *sender = &ss->xtnData.serverSenders[0];
  1.1907 +
  1.1908 +    for (i = 0; i < SSL_MAX_EXTENSIONS; ++i, ++sender) {
  1.1909 +        if (!sender->ex_sender) {
  1.1910 +            sender->ex_type   = ex_type;
  1.1911 +            sender->ex_sender = cb;
  1.1912 +            return SECSuccess;
  1.1913 +        }
  1.1914 +        /* detect duplicate senders */
  1.1915 +        PORT_Assert(sender->ex_type != ex_type);
  1.1916 +        if (sender->ex_type == ex_type) {
  1.1917 +            /* duplicate */
  1.1918 +            break;
  1.1919 +        }
  1.1920 +    }
  1.1921 +    PORT_Assert(i < SSL_MAX_EXTENSIONS); /* table needs to grow */
  1.1922 +    PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
  1.1923 +    return SECFailure;
  1.1924 +}
  1.1925 +
  1.1926 +/* call each of the extension senders and return the accumulated length */
  1.1927 +PRInt32
  1.1928 +ssl3_CallHelloExtensionSenders(sslSocket *ss, PRBool append, PRUint32 maxBytes,
  1.1929 +                               const ssl3HelloExtensionSender *sender)
  1.1930 +{
  1.1931 +    PRInt32 total_exten_len = 0;
  1.1932 +    int i;
  1.1933 +
  1.1934 +    if (!sender) {
  1.1935 +        sender = ss->version > SSL_LIBRARY_VERSION_3_0 ?
  1.1936 +                 &clientHelloSendersTLS[0] : &clientHelloSendersSSL3[0];
  1.1937 +    }
  1.1938 +
  1.1939 +    for (i = 0; i < SSL_MAX_EXTENSIONS; ++i, ++sender) {
  1.1940 +        if (sender->ex_sender) {
  1.1941 +            PRInt32 extLen = (*sender->ex_sender)(ss, append, maxBytes);
  1.1942 +            if (extLen < 0)
  1.1943 +                return -1;
  1.1944 +            maxBytes        -= extLen;
  1.1945 +            total_exten_len += extLen;
  1.1946 +        }
  1.1947 +    }
  1.1948 +    return total_exten_len;
  1.1949 +}
  1.1950 +
  1.1951 +
  1.1952 +/* Extension format:
  1.1953 + * Extension number:   2 bytes
  1.1954 + * Extension length:   2 bytes
  1.1955 + * Verify Data Length: 1 byte
  1.1956 + * Verify Data (TLS): 12 bytes (client) or 24 bytes (server)
  1.1957 + * Verify Data (SSL): 36 bytes (client) or 72 bytes (server)
  1.1958 + */
  1.1959 +static PRInt32
  1.1960 +ssl3_SendRenegotiationInfoXtn(
  1.1961 +                        sslSocket * ss,
  1.1962 +                        PRBool      append,
  1.1963 +                        PRUint32    maxBytes)
  1.1964 +{
  1.1965 +    PRInt32 len, needed;
  1.1966 +
  1.1967 +    /* In draft-ietf-tls-renegotiation-03, it is NOT RECOMMENDED to send
  1.1968 +     * both the SCSV and the empty RI, so when we send SCSV in
  1.1969 +     * the initial handshake, we don't also send RI.
  1.1970 +     */
  1.1971 +    if (!ss || ss->ssl3.hs.sendingSCSV)
  1.1972 +        return 0;
  1.1973 +    len = !ss->firstHsDone ? 0 :
  1.1974 +           (ss->sec.isServer ? ss->ssl3.hs.finishedBytes * 2
  1.1975 +                             : ss->ssl3.hs.finishedBytes);
  1.1976 +    needed = 5 + len;
  1.1977 +    if (append && maxBytes >= needed) {
  1.1978 +        SECStatus rv;
  1.1979 +        /* extension_type */
  1.1980 +        rv = ssl3_AppendHandshakeNumber(ss, ssl_renegotiation_info_xtn, 2);
  1.1981 +        if (rv != SECSuccess) return -1;
  1.1982 +        /* length of extension_data */
  1.1983 +        rv = ssl3_AppendHandshakeNumber(ss, len + 1, 2);
  1.1984 +        if (rv != SECSuccess) return -1;
  1.1985 +        /* verify_Data from previous Finished message(s) */
  1.1986 +        rv = ssl3_AppendHandshakeVariable(ss,
  1.1987 +                  ss->ssl3.hs.finishedMsgs.data, len, 1);
  1.1988 +        if (rv != SECSuccess) return -1;
  1.1989 +        if (!ss->sec.isServer) {
  1.1990 +            TLSExtensionData *xtnData = &ss->xtnData;
  1.1991 +            xtnData->advertised[xtnData->numAdvertised++] =
  1.1992 +                                                   ssl_renegotiation_info_xtn;
  1.1993 +        }
  1.1994 +    }
  1.1995 +    return needed;
  1.1996 +}
  1.1997 +
  1.1998 +static SECStatus
  1.1999 +ssl3_ServerHandleStatusRequestXtn(sslSocket *ss, PRUint16 ex_type,
  1.2000 +                                  SECItem *data)
  1.2001 +{
  1.2002 +    SECStatus rv = SECSuccess;
  1.2003 +
  1.2004 +    /* remember that we got this extension. */
  1.2005 +    ss->xtnData.negotiated[ss->xtnData.numNegotiated++] = ex_type;
  1.2006 +    PORT_Assert(ss->sec.isServer);
  1.2007 +    /* prepare to send back the appropriate response */
  1.2008 +    rv = ssl3_RegisterServerHelloExtensionSender(ss, ex_type,
  1.2009 +                                            ssl3_ServerSendStatusRequestXtn);
  1.2010 +    return rv;
  1.2011 +}
  1.2012 +
  1.2013 +/* This function runs in both the client and server.  */
  1.2014 +static SECStatus
  1.2015 +ssl3_HandleRenegotiationInfoXtn(sslSocket *ss, PRUint16 ex_type, SECItem *data)
  1.2016 +{
  1.2017 +    SECStatus rv = SECSuccess;
  1.2018 +    PRUint32 len = 0;
  1.2019 +
  1.2020 +    if (ss->firstHsDone) {
  1.2021 +        len = ss->sec.isServer ? ss->ssl3.hs.finishedBytes
  1.2022 +                               : ss->ssl3.hs.finishedBytes * 2;
  1.2023 +    }
  1.2024 +    if (data->len != 1 + len  ||
  1.2025 +        data->data[0] != len  || (len &&
  1.2026 +        NSS_SecureMemcmp(ss->ssl3.hs.finishedMsgs.data,
  1.2027 +                         data->data + 1, len))) {
  1.2028 +        /* Can we do this here? Or, must we arrange for the caller to do it? */
  1.2029 +        (void)SSL3_SendAlert(ss, alert_fatal, handshake_failure);
  1.2030 +        PORT_SetError(SSL_ERROR_BAD_HANDSHAKE_HASH_VALUE);
  1.2031 +        return SECFailure;
  1.2032 +    }
  1.2033 +    /* remember that we got this extension and it was correct. */
  1.2034 +    ss->peerRequestedProtection = 1;
  1.2035 +    ss->xtnData.negotiated[ss->xtnData.numNegotiated++] = ex_type;
  1.2036 +    if (ss->sec.isServer) {
  1.2037 +        /* prepare to send back the appropriate response */
  1.2038 +        rv = ssl3_RegisterServerHelloExtensionSender(ss, ex_type,
  1.2039 +                                             ssl3_SendRenegotiationInfoXtn);
  1.2040 +    }
  1.2041 +    return rv;
  1.2042 +}
  1.2043 +
  1.2044 +static PRInt32
  1.2045 +ssl3_SendUseSRTPXtn(sslSocket *ss, PRBool append, PRUint32 maxBytes)
  1.2046 +{
  1.2047 +    PRUint32 ext_data_len;
  1.2048 +    PRInt16 i;
  1.2049 +    SECStatus rv;
  1.2050 +
  1.2051 +    if (!ss)
  1.2052 +        return 0;
  1.2053 +
  1.2054 +    if (!ss->sec.isServer) {
  1.2055 +        /* Client side */
  1.2056 +
  1.2057 +        if (!IS_DTLS(ss) || !ss->ssl3.dtlsSRTPCipherCount)
  1.2058 +            return 0;  /* Not relevant */
  1.2059 +
  1.2060 +        ext_data_len = 2 + 2 * ss->ssl3.dtlsSRTPCipherCount + 1;
  1.2061 +
  1.2062 +        if (append && maxBytes >= 4 + ext_data_len) {
  1.2063 +            /* Extension type */
  1.2064 +            rv = ssl3_AppendHandshakeNumber(ss, ssl_use_srtp_xtn, 2);
  1.2065 +            if (rv != SECSuccess) return -1;
  1.2066 +            /* Length of extension data */
  1.2067 +            rv = ssl3_AppendHandshakeNumber(ss, ext_data_len, 2);
  1.2068 +            if (rv != SECSuccess) return -1;
  1.2069 +            /* Length of the SRTP cipher list */
  1.2070 +            rv = ssl3_AppendHandshakeNumber(ss,
  1.2071 +                                            2 * ss->ssl3.dtlsSRTPCipherCount,
  1.2072 +                                            2);
  1.2073 +            if (rv != SECSuccess) return -1;
  1.2074 +            /* The SRTP ciphers */
  1.2075 +            for (i = 0; i < ss->ssl3.dtlsSRTPCipherCount; i++) {
  1.2076 +                rv = ssl3_AppendHandshakeNumber(ss,
  1.2077 +                                                ss->ssl3.dtlsSRTPCiphers[i],
  1.2078 +                                                2);
  1.2079 +            }
  1.2080 +            /* Empty MKI value */
  1.2081 +            ssl3_AppendHandshakeVariable(ss, NULL, 0, 1);
  1.2082 +
  1.2083 +            ss->xtnData.advertised[ss->xtnData.numAdvertised++] =
  1.2084 +                ssl_use_srtp_xtn;
  1.2085 +        }
  1.2086 +
  1.2087 +        return 4 + ext_data_len;
  1.2088 +    }
  1.2089 +
  1.2090 +    /* Server side */
  1.2091 +    if (append && maxBytes >= 9) {
  1.2092 +        /* Extension type */
  1.2093 +        rv = ssl3_AppendHandshakeNumber(ss, ssl_use_srtp_xtn, 2);
  1.2094 +        if (rv != SECSuccess) return -1;
  1.2095 +        /* Length of extension data */
  1.2096 +        rv = ssl3_AppendHandshakeNumber(ss, 5, 2);
  1.2097 +        if (rv != SECSuccess) return -1;
  1.2098 +        /* Length of the SRTP cipher list */
  1.2099 +        rv = ssl3_AppendHandshakeNumber(ss, 2, 2);
  1.2100 +        if (rv != SECSuccess) return -1;
  1.2101 +        /* The selected cipher */
  1.2102 +        rv = ssl3_AppendHandshakeNumber(ss, ss->ssl3.dtlsSRTPCipherSuite, 2);
  1.2103 +        if (rv != SECSuccess) return -1;
  1.2104 +        /* Empty MKI value */
  1.2105 +        ssl3_AppendHandshakeVariable(ss, NULL, 0, 1);
  1.2106 +    }
  1.2107 +
  1.2108 +    return 9;
  1.2109 +}
  1.2110 +
  1.2111 +static SECStatus
  1.2112 +ssl3_HandleUseSRTPXtn(sslSocket * ss, PRUint16 ex_type, SECItem *data)
  1.2113 +{
  1.2114 +    SECStatus rv;
  1.2115 +    SECItem ciphers = {siBuffer, NULL, 0};
  1.2116 +    PRUint16 i;
  1.2117 +    unsigned int j;
  1.2118 +    PRUint16 cipher = 0;
  1.2119 +    PRBool found = PR_FALSE;
  1.2120 +    SECItem litem;
  1.2121 +
  1.2122 +    if (!ss->sec.isServer) {
  1.2123 +        /* Client side */
  1.2124 +        if (!data->data || !data->len) {
  1.2125 +            /* malformed */
  1.2126 +            return SECFailure;
  1.2127 +        }
  1.2128 +
  1.2129 +        /* Get the cipher list */
  1.2130 +        rv = ssl3_ConsumeHandshakeVariable(ss, &ciphers, 2,
  1.2131 +                                           &data->data, &data->len);
  1.2132 +        if (rv != SECSuccess) {
  1.2133 +            return SECFailure;
  1.2134 +        }
  1.2135 +        /* Now check that the number of ciphers listed is 1 (len = 2) */
  1.2136 +        if (ciphers.len != 2) {
  1.2137 +            return SECFailure;
  1.2138 +        }
  1.2139 +
  1.2140 +        /* Get the selected cipher */
  1.2141 +        cipher = (ciphers.data[0] << 8) | ciphers.data[1];
  1.2142 +
  1.2143 +        /* Now check that this is one of the ciphers we offered */
  1.2144 +        for (i = 0; i < ss->ssl3.dtlsSRTPCipherCount; i++) {
  1.2145 +            if (cipher == ss->ssl3.dtlsSRTPCiphers[i]) {
  1.2146 +                found = PR_TRUE;
  1.2147 +                break;
  1.2148 +            }
  1.2149 +        }
  1.2150 +
  1.2151 +        if (!found) {
  1.2152 +            return SECFailure;
  1.2153 +        }
  1.2154 +
  1.2155 +        /* Get the srtp_mki value */
  1.2156 +        rv = ssl3_ConsumeHandshakeVariable(ss, &litem, 1,
  1.2157 +                                           &data->data, &data->len);
  1.2158 +        if (rv != SECSuccess) {
  1.2159 +            return SECFailure;
  1.2160 +        }
  1.2161 +
  1.2162 +        /* We didn't offer an MKI, so this must be 0 length */
  1.2163 +        /* XXX RFC 5764 Section 4.1.3 says:
  1.2164 +         *   If the client detects a nonzero-length MKI in the server's
  1.2165 +         *   response that is different than the one the client offered,
  1.2166 +         *   then the client MUST abort the handshake and SHOULD send an
  1.2167 +         *   invalid_parameter alert.
  1.2168 +         *
  1.2169 +         * Due to a limitation of the ssl3_HandleHelloExtensions function,
  1.2170 +         * returning SECFailure here won't abort the handshake.  It will
  1.2171 +         * merely cause the use_srtp extension to be not negotiated.  We
  1.2172 +         * should fix this.  See NSS bug 753136.
  1.2173 +         */
  1.2174 +        if (litem.len != 0) {
  1.2175 +            return SECFailure;
  1.2176 +        }
  1.2177 +
  1.2178 +        if (data->len != 0) {
  1.2179 +            /* malformed */
  1.2180 +            return SECFailure;
  1.2181 +        }
  1.2182 +
  1.2183 +        /* OK, this looks fine. */
  1.2184 +        ss->xtnData.negotiated[ss->xtnData.numNegotiated++] = ssl_use_srtp_xtn;
  1.2185 +        ss->ssl3.dtlsSRTPCipherSuite = cipher;
  1.2186 +        return SECSuccess;
  1.2187 +    }
  1.2188 +
  1.2189 +    /* Server side */
  1.2190 +    if (!IS_DTLS(ss) || !ss->ssl3.dtlsSRTPCipherCount) {
  1.2191 +        /* Ignore the extension if we aren't doing DTLS or no DTLS-SRTP
  1.2192 +         * preferences have been set. */
  1.2193 +        return SECSuccess;
  1.2194 +    }
  1.2195 +
  1.2196 +    if (!data->data || data->len < 5) {
  1.2197 +        /* malformed */
  1.2198 +        return SECFailure;
  1.2199 +    }
  1.2200 +
  1.2201 +    /* Get the cipher list */
  1.2202 +    rv = ssl3_ConsumeHandshakeVariable(ss, &ciphers, 2,
  1.2203 +                                       &data->data, &data->len);
  1.2204 +    if (rv != SECSuccess) {
  1.2205 +        return SECFailure;
  1.2206 +    }
  1.2207 +    /* Check that the list is even length */
  1.2208 +    if (ciphers.len % 2) {
  1.2209 +        return SECFailure;
  1.2210 +    }
  1.2211 +
  1.2212 +    /* Walk through the offered list and pick the most preferred of our
  1.2213 +     * ciphers, if any */
  1.2214 +    for (i = 0; !found && i < ss->ssl3.dtlsSRTPCipherCount; i++) {
  1.2215 +        for (j = 0; j + 1 < ciphers.len; j += 2) {
  1.2216 +            cipher = (ciphers.data[j] << 8) | ciphers.data[j + 1];
  1.2217 +            if (cipher == ss->ssl3.dtlsSRTPCiphers[i]) {
  1.2218 +                found = PR_TRUE;
  1.2219 +                break;
  1.2220 +            }
  1.2221 +        }
  1.2222 +    }
  1.2223 +
  1.2224 +    /* Get the srtp_mki value */
  1.2225 +    rv = ssl3_ConsumeHandshakeVariable(ss, &litem, 1, &data->data, &data->len);
  1.2226 +    if (rv != SECSuccess) {
  1.2227 +        return SECFailure;
  1.2228 +    }
  1.2229 +
  1.2230 +    if (data->len != 0) {
  1.2231 +        return SECFailure; /* Malformed */
  1.2232 +    }
  1.2233 +
  1.2234 +    /* Now figure out what to do */
  1.2235 +    if (!found) {
  1.2236 +        /* No matching ciphers */
  1.2237 +        return SECSuccess;
  1.2238 +    }
  1.2239 +
  1.2240 +    /* OK, we have a valid cipher and we've selected it */
  1.2241 +    ss->ssl3.dtlsSRTPCipherSuite = cipher;
  1.2242 +    ss->xtnData.negotiated[ss->xtnData.numNegotiated++] = ssl_use_srtp_xtn;
  1.2243 +
  1.2244 +    return ssl3_RegisterServerHelloExtensionSender(ss, ssl_use_srtp_xtn,
  1.2245 +                                                   ssl3_SendUseSRTPXtn);
  1.2246 +}
  1.2247 +
  1.2248 +/* ssl3_ServerHandleSigAlgsXtn handles the signature_algorithms extension
  1.2249 + * from a client.
  1.2250 + * See https://tools.ietf.org/html/rfc5246#section-7.4.1.4.1 */
  1.2251 +static SECStatus
  1.2252 +ssl3_ServerHandleSigAlgsXtn(sslSocket * ss, PRUint16 ex_type, SECItem *data)
  1.2253 +{
  1.2254 +    SECStatus rv;
  1.2255 +    SECItem algorithms;
  1.2256 +    const unsigned char *b;
  1.2257 +    unsigned int numAlgorithms, i;
  1.2258 +
  1.2259 +    /* Ignore this extension if we aren't doing TLS 1.2 or greater. */
  1.2260 +    if (ss->version < SSL_LIBRARY_VERSION_TLS_1_2) {
  1.2261 +        return SECSuccess;
  1.2262 +    }
  1.2263 +
  1.2264 +    /* Keep track of negotiated extensions. */
  1.2265 +    ss->xtnData.negotiated[ss->xtnData.numNegotiated++] = ex_type;
  1.2266 +
  1.2267 +    rv = ssl3_ConsumeHandshakeVariable(ss, &algorithms, 2, &data->data,
  1.2268 +                                       &data->len);
  1.2269 +    if (rv != SECSuccess) {
  1.2270 +        return SECFailure;
  1.2271 +    }
  1.2272 +    /* Trailing data, empty value, or odd-length value is invalid. */
  1.2273 +    if (data->len != 0 || algorithms.len == 0 || (algorithms.len & 1) != 0) {
  1.2274 +        PORT_SetError(SSL_ERROR_RX_MALFORMED_CLIENT_HELLO);
  1.2275 +        return SECFailure;
  1.2276 +    }
  1.2277 +
  1.2278 +    numAlgorithms = algorithms.len/2;
  1.2279 +
  1.2280 +    /* We don't care to process excessive numbers of algorithms. */
  1.2281 +    if (numAlgorithms > 512) {
  1.2282 +        numAlgorithms = 512;
  1.2283 +    }
  1.2284 +
  1.2285 +    ss->ssl3.hs.clientSigAndHash =
  1.2286 +            PORT_NewArray(SSL3SignatureAndHashAlgorithm, numAlgorithms);
  1.2287 +    if (!ss->ssl3.hs.clientSigAndHash) {
  1.2288 +        return SECFailure;
  1.2289 +    }
  1.2290 +    ss->ssl3.hs.numClientSigAndHash = 0;
  1.2291 +
  1.2292 +    b = algorithms.data;
  1.2293 +    for (i = 0; i < numAlgorithms; i++) {
  1.2294 +        unsigned char tls_hash = *(b++);
  1.2295 +        unsigned char tls_sig = *(b++);
  1.2296 +        SECOidTag hash = ssl3_TLSHashAlgorithmToOID(tls_hash);
  1.2297 +
  1.2298 +        if (hash == SEC_OID_UNKNOWN) {
  1.2299 +            /* We ignore formats that we don't understand. */
  1.2300 +            continue;
  1.2301 +        }
  1.2302 +        /* tls_sig support will be checked later in
  1.2303 +         * ssl3_PickSignatureHashAlgorithm. */
  1.2304 +        ss->ssl3.hs.clientSigAndHash[i].hashAlg = hash;
  1.2305 +        ss->ssl3.hs.clientSigAndHash[i].sigAlg = tls_sig;
  1.2306 +        ss->ssl3.hs.numClientSigAndHash++;
  1.2307 +    }
  1.2308 +
  1.2309 +    if (!ss->ssl3.hs.numClientSigAndHash) {
  1.2310 +        /* We didn't understand any of the client's requested signature
  1.2311 +         * formats. We'll use the defaults. */
  1.2312 +        PORT_Free(ss->ssl3.hs.clientSigAndHash);
  1.2313 +        ss->ssl3.hs.clientSigAndHash = NULL;
  1.2314 +    }
  1.2315 +
  1.2316 +    return SECSuccess;
  1.2317 +}
  1.2318 +
  1.2319 +/* ssl3_ClientSendSigAlgsXtn sends the signature_algorithm extension for TLS
  1.2320 + * 1.2 ClientHellos. */
  1.2321 +static PRInt32
  1.2322 +ssl3_ClientSendSigAlgsXtn(sslSocket * ss, PRBool append, PRUint32 maxBytes)
  1.2323 +{
  1.2324 +    static const unsigned char signatureAlgorithms[] = {
  1.2325 +        /* This block is the contents of our signature_algorithms extension, in
  1.2326 +         * wire format. See
  1.2327 +         * https://tools.ietf.org/html/rfc5246#section-7.4.1.4.1 */
  1.2328 +        tls_hash_sha256, tls_sig_rsa,
  1.2329 +        tls_hash_sha384, tls_sig_rsa,
  1.2330 +        tls_hash_sha1,   tls_sig_rsa,
  1.2331 +#ifndef NSS_DISABLE_ECC
  1.2332 +        tls_hash_sha256, tls_sig_ecdsa,
  1.2333 +        tls_hash_sha384, tls_sig_ecdsa,
  1.2334 +        tls_hash_sha1,   tls_sig_ecdsa,
  1.2335 +#endif
  1.2336 +        tls_hash_sha256, tls_sig_dsa,
  1.2337 +        tls_hash_sha1,   tls_sig_dsa,
  1.2338 +    };
  1.2339 +    PRInt32 extension_length;
  1.2340 +
  1.2341 +    if (ss->version < SSL_LIBRARY_VERSION_TLS_1_2) {
  1.2342 +        return 0;
  1.2343 +    }
  1.2344 +
  1.2345 +    extension_length =
  1.2346 +        2 /* extension type */ +
  1.2347 +        2 /* extension length */ +
  1.2348 +        2 /* supported_signature_algorithms length */ +
  1.2349 +        sizeof(signatureAlgorithms);
  1.2350 +
  1.2351 +    if (append && maxBytes >= extension_length) {
  1.2352 +        SECStatus rv;
  1.2353 +        rv = ssl3_AppendHandshakeNumber(ss, ssl_signature_algorithms_xtn, 2);
  1.2354 +        if (rv != SECSuccess)
  1.2355 +            goto loser;
  1.2356 +        rv = ssl3_AppendHandshakeNumber(ss, extension_length - 4, 2);
  1.2357 +        if (rv != SECSuccess)
  1.2358 +            goto loser;
  1.2359 +        rv = ssl3_AppendHandshakeVariable(ss, signatureAlgorithms,
  1.2360 +                                          sizeof(signatureAlgorithms), 2);
  1.2361 +        if (rv != SECSuccess)
  1.2362 +            goto loser;
  1.2363 +        ss->xtnData.advertised[ss->xtnData.numAdvertised++] =
  1.2364 +                ssl_signature_algorithms_xtn;
  1.2365 +    } else if (maxBytes < extension_length) {
  1.2366 +        PORT_Assert(0);
  1.2367 +        return 0;
  1.2368 +    }
  1.2369 +
  1.2370 +    return extension_length;
  1.2371 +
  1.2372 +loser:
  1.2373 +    return -1;
  1.2374 +}
  1.2375 +
  1.2376 +unsigned int
  1.2377 +ssl3_CalculatePaddingExtensionLength(unsigned int clientHelloLength)
  1.2378 +{
  1.2379 +    unsigned int recordLength = 1 /* handshake message type */ +
  1.2380 +                                3 /* handshake message length */ +
  1.2381 +                                clientHelloLength;
  1.2382 +    unsigned int extensionLength;
  1.2383 +
  1.2384 +    if (recordLength < 256 || recordLength >= 512) {
  1.2385 +        return 0;
  1.2386 +    }
  1.2387 +
  1.2388 +    extensionLength = 512 - recordLength;
  1.2389 +    /* Extensions take at least four bytes to encode. */
  1.2390 +    if (extensionLength < 4) {
  1.2391 +        extensionLength = 4;
  1.2392 +    }
  1.2393 +
  1.2394 +    return extensionLength;
  1.2395 +}
  1.2396 +
  1.2397 +/* ssl3_AppendPaddingExtension possibly adds an extension which ensures that a
  1.2398 + * ClientHello record is either < 256 bytes or is >= 512 bytes. This ensures
  1.2399 + * that we don't trigger bugs in F5 products. */
  1.2400 +PRInt32
  1.2401 +ssl3_AppendPaddingExtension(sslSocket *ss, unsigned int extensionLen,
  1.2402 +                            PRUint32 maxBytes)
  1.2403 +{
  1.2404 +    unsigned int paddingLen = extensionLen - 4;
  1.2405 +    static unsigned char padding[256];
  1.2406 +
  1.2407 +    if (extensionLen == 0) {
  1.2408 +        return 0;
  1.2409 +    }
  1.2410 +
  1.2411 +    if (extensionLen < 4 ||
  1.2412 +        extensionLen > maxBytes ||
  1.2413 +        paddingLen > sizeof(padding)) {
  1.2414 +        PORT_Assert(0);
  1.2415 +        return -1;
  1.2416 +    }
  1.2417 +
  1.2418 +    if (SECSuccess != ssl3_AppendHandshakeNumber(ss, ssl_padding_xtn, 2))
  1.2419 +        return -1;
  1.2420 +    if (SECSuccess != ssl3_AppendHandshakeNumber(ss, paddingLen, 2))
  1.2421 +        return -1;
  1.2422 +    if (SECSuccess != ssl3_AppendHandshake(ss, padding, paddingLen))
  1.2423 +        return -1;
  1.2424 +
  1.2425 +    return extensionLen;
  1.2426 +}

mercurial