15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * SSL3 Protocol
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
42a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * This Source Code Form is subject to the terms of the Mozilla Public
52a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * License, v. 2.0. If a copy of the MPL was not distributed with this
62a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* TLS extension code moved here from ssl3ecc.c */
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "nssrenam.h"
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "nss.h"
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ssl.h"
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "sslimpl.h"
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "sslproto.h"
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "pk11pub.h"
162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#ifdef NO_PKCS11_BYPASS
172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "blapit.h"
182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#else
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "blapi.h"
202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "prinit.h"
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static unsigned char  key_name[SESS_TICKET_KEY_NAME_LEN];
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static PK11SymKey    *session_ticket_enc_key_pkcs11 = NULL;
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static PK11SymKey    *session_ticket_mac_key_pkcs11 = NULL;
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#ifndef NO_PKCS11_BYPASS
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static unsigned char  session_ticket_enc_key[AES_256_KEY_LENGTH];
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static unsigned char  session_ticket_mac_key[SHA256_LENGTH];
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static PRBool         session_ticket_keys_initialized = PR_FALSE;
322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static PRCallOnceType generate_session_keys_once;
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* forward static function declarations */
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static SECStatus ssl3_ParseEncryptedSessionTicket(sslSocket *ss,
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SECItem *data, EncryptedSessionTicket *enc_session_ticket);
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static SECStatus ssl3_AppendToItem(SECItem *item, const unsigned char *buf,
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PRUint32 bytes);
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static SECStatus ssl3_AppendNumberToItem(SECItem *item, PRUint32 num,
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PRInt32 lenSize);
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static SECStatus ssl3_GetSessionTicketKeysPKCS11(sslSocket *ss,
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PK11SymKey **aes_key, PK11SymKey **mac_key);
442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#ifndef NO_PKCS11_BYPASS
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static SECStatus ssl3_GetSessionTicketKeys(const unsigned char **aes_key,
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PRUint32 *aes_key_length, const unsigned char **mac_key,
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PRUint32 *mac_key_length);
482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static PRInt32 ssl3_SendRenegotiationInfoXtn(sslSocket * ss,
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PRBool append, PRUint32 maxBytes);
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static SECStatus ssl3_HandleRenegotiationInfoXtn(sslSocket *ss,
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PRUint16 ex_type, SECItem *data);
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static SECStatus ssl3_ClientHandleNextProtoNegoXtn(sslSocket *ss,
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			PRUint16 ex_type, SECItem *data);
55eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochstatic SECStatus ssl3_ClientHandleAppProtoXtn(sslSocket *ss,
56eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch			PRUint16 ex_type, SECItem *data);
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static SECStatus ssl3_ServerHandleNextProtoNegoXtn(sslSocket *ss,
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			PRUint16 ex_type, SECItem *data);
59eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochstatic PRInt32 ssl3_ClientSendAppProtoXtn(sslSocket *ss, PRBool append,
60eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch					       PRUint32 maxBytes);
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static PRInt32 ssl3_ClientSendNextProtoNegoXtn(sslSocket *ss, PRBool append,
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)					       PRUint32 maxBytes);
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static PRInt32 ssl3_SendUseSRTPXtn(sslSocket *ss, PRBool append,
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PRUint32 maxBytes);
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static SECStatus ssl3_HandleUseSRTPXtn(sslSocket * ss, PRUint16 ex_type,
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SECItem *data);
672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)static SECStatus ssl3_ClientHandleChannelIDXtn(sslSocket *ss,
682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    PRUint16 ex_type, SECItem *data);
692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)static PRInt32 ssl3_ClientSendChannelIDXtn(sslSocket *ss, PRBool append,
702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    PRUint32 maxBytes);
71c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)static SECStatus ssl3_ServerSendStatusRequestXtn(sslSocket * ss,
72a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    PRBool append, PRUint32 maxBytes);
73c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)static SECStatus ssl3_ServerHandleStatusRequestXtn(sslSocket *ss,
74c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    PRUint16 ex_type, SECItem *data);
75c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)static SECStatus ssl3_ClientHandleStatusRequestXtn(sslSocket *ss,
76a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)                                                   PRUint16 ex_type,
77a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)                                                   SECItem *data);
78c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)static PRInt32 ssl3_ClientSendStatusRequestXtn(sslSocket * ss, PRBool append,
79a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)                                               PRUint32 maxBytes);
80868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)static PRInt32 ssl3_ClientSendSigAlgsXtn(sslSocket *ss, PRBool append,
81868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                                         PRUint32 maxBytes);
82868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)static SECStatus ssl3_ServerHandleSigAlgsXtn(sslSocket *ss, PRUint16 ex_type,
83868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                                             SECItem *data);
84f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)static PRInt32 ssl3_ClientSendSignedCertTimestampXtn(sslSocket *ss,
85f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)						     PRBool append,
86f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)						     PRUint32 maxBytes);
87f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)static SECStatus ssl3_ClientHandleSignedCertTimestampXtn(sslSocket *ss,
88f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)							 PRUint16 ex_type,
89f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)							 SECItem *data);
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Write bytes.  Using this function means the SECItem structure
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * cannot be freed.  The caller is expected to call this function
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * on a shallow copy of the structure.
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static SECStatus
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ssl3_AppendToItem(SECItem *item, const unsigned char *buf, PRUint32 bytes)
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (bytes > item->len)
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return SECFailure;
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PORT_Memcpy(item->data, buf, bytes);
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    item->data += bytes;
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    item->len -= bytes;
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return SECSuccess;
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Write a number in network byte order. Using this function means the
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * SECItem structure cannot be freed.  The caller is expected to call
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * this function on a shallow copy of the structure.
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static SECStatus
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ssl3_AppendNumberToItem(SECItem *item, PRUint32 num, PRInt32 lenSize)
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SECStatus rv;
117a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    PRUint8   b[4];
118a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    PRUint8 * p = b;
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    switch (lenSize) {
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case 4:
122a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)	*p++ = (PRUint8) (num >> 24);
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case 3:
124a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)	*p++ = (PRUint8) (num >> 16);
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case 2:
126a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)	*p++ = (PRUint8) (num >> 8);
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case 1:
128a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)	*p = (PRUint8) num;
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rv = ssl3_AppendToItem(item, &b[0], lenSize);
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return rv;
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static SECStatus ssl3_SessionTicketShutdown(void* appData, void* nssData)
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (session_ticket_enc_key_pkcs11) {
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	PK11_FreeSymKey(session_ticket_enc_key_pkcs11);
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	session_ticket_enc_key_pkcs11 = NULL;
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (session_ticket_mac_key_pkcs11) {
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	PK11_FreeSymKey(session_ticket_mac_key_pkcs11);
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	session_ticket_mac_key_pkcs11 = NULL;
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PORT_Memset(&generate_session_keys_once, 0,
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	sizeof(generate_session_keys_once));
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return SECSuccess;
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static PRStatus
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ssl3_GenerateSessionTicketKeysPKCS11(void *data)
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SECStatus rv;
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sslSocket *ss = (sslSocket *)data;
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SECKEYPrivateKey *svrPrivKey = ss->serverCerts[kt_rsa].SERVERKEY;
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SECKEYPublicKey *svrPubKey = ss->serverCerts[kt_rsa].serverKeyPair->pubKey;
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (svrPrivKey == NULL || svrPubKey == NULL) {
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	SSL_DBG(("%d: SSL[%d]: Pub or priv key(s) is NULL.",
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			SSL_GETPID(), ss->fd));
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	goto loser;
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /* Get a copy of the session keys from shared memory. */
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PORT_Memcpy(key_name, SESS_TICKET_KEY_NAME_PREFIX,
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	sizeof(SESS_TICKET_KEY_NAME_PREFIX));
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!ssl_GetSessionTicketKeysPKCS11(svrPrivKey, svrPubKey,
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    ss->pkcs11PinArg, &key_name[SESS_TICKET_KEY_NAME_PREFIX_LEN],
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    &session_ticket_enc_key_pkcs11, &session_ticket_mac_key_pkcs11))
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return PR_FAILURE;
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rv = NSS_RegisterShutdown(ssl3_SessionTicketShutdown, NULL);
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (rv != SECSuccess)
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	goto loser;
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return PR_SUCCESS;
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)loser:
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ssl3_SessionTicketShutdown(NULL, NULL);
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return PR_FAILURE;
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static SECStatus
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ssl3_GetSessionTicketKeysPKCS11(sslSocket *ss, PK11SymKey **aes_key,
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                PK11SymKey **mac_key)
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (PR_CallOnceWithArg(&generate_session_keys_once,
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    ssl3_GenerateSessionTicketKeysPKCS11, ss) != PR_SUCCESS)
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return SECFailure;
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (session_ticket_enc_key_pkcs11 == NULL ||
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	session_ticket_mac_key_pkcs11 == NULL)
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return SECFailure;
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    *aes_key = session_ticket_enc_key_pkcs11;
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    *mac_key = session_ticket_mac_key_pkcs11;
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return SECSuccess;
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#ifndef NO_PKCS11_BYPASS
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static PRStatus
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ssl3_GenerateSessionTicketKeys(void)
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PORT_Memcpy(key_name, SESS_TICKET_KEY_NAME_PREFIX,
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	sizeof(SESS_TICKET_KEY_NAME_PREFIX));
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!ssl_GetSessionTicketKeys(&key_name[SESS_TICKET_KEY_NAME_PREFIX_LEN],
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    session_ticket_enc_key, session_ticket_mac_key))
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return PR_FAILURE;
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    session_ticket_keys_initialized = PR_TRUE;
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return PR_SUCCESS;
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static SECStatus
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ssl3_GetSessionTicketKeys(const unsigned char **aes_key,
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PRUint32 *aes_key_length, const unsigned char **mac_key,
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PRUint32 *mac_key_length)
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (PR_CallOnce(&generate_session_keys_once,
221a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)	    ssl3_GenerateSessionTicketKeys) != PR_SUCCESS)
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return SECFailure;
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!session_ticket_keys_initialized)
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return SECFailure;
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    *aes_key = session_ticket_enc_key;
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    *aes_key_length = sizeof(session_ticket_enc_key);
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    *mac_key = session_ticket_mac_key;
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    *mac_key_length = sizeof(session_ticket_mac_key);
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return SECSuccess;
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* Table of handlers for received TLS hello extensions, one per extension.
2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * In the second generation, this table will be dynamic, and functions
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * will be registered here.
2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* This table is used by the server, to handle client hello extensions. */
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const ssl3HelloExtensionHandler clientHelloHandlers[] = {
2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { ssl_server_name_xtn,        &ssl3_HandleServerNameXtn },
2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef NSS_ENABLE_ECC
2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { ssl_elliptic_curves_xtn,    &ssl3_HandleSupportedCurvesXtn },
2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { ssl_ec_point_formats_xtn,   &ssl3_HandleSupportedPointFormatsXtn },
2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { ssl_session_ticket_xtn,     &ssl3_ServerHandleSessionTicketXtn },
2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { ssl_renegotiation_info_xtn, &ssl3_HandleRenegotiationInfoXtn },
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { ssl_next_proto_nego_xtn,    &ssl3_ServerHandleNextProtoNegoXtn },
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { ssl_use_srtp_xtn,           &ssl3_HandleUseSRTPXtn },
251c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    { ssl_cert_status_xtn,        &ssl3_ServerHandleStatusRequestXtn },
252868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    { ssl_signature_algorithms_xtn, &ssl3_ServerHandleSigAlgsXtn },
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { -1, NULL }
2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* These two tables are used by the client, to handle server hello
2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * extensions. */
2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const ssl3HelloExtensionHandler serverHelloHandlersTLS[] = {
259a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    { ssl_server_name_xtn,        &ssl3_HandleServerNameXtn },
2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /* TODO: add a handler for ssl_ec_point_formats_xtn */
261a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    { ssl_session_ticket_xtn,     &ssl3_ClientHandleSessionTicketXtn },
262a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    { ssl_renegotiation_info_xtn, &ssl3_HandleRenegotiationInfoXtn },
263a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    { ssl_next_proto_nego_xtn,    &ssl3_ClientHandleNextProtoNegoXtn },
264a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    { ssl_app_layer_protocol_xtn, &ssl3_ClientHandleAppProtoXtn },
265a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    { ssl_use_srtp_xtn,           &ssl3_HandleUseSRTPXtn },
266a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    { ssl_channel_id_xtn,         &ssl3_ClientHandleChannelIDXtn },
267a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    { ssl_cert_status_xtn,        &ssl3_ClientHandleStatusRequestXtn },
268f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    { ssl_signed_certificate_timestamp_xtn,
269f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      &ssl3_ClientHandleSignedCertTimestampXtn },
2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { -1, NULL }
2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const ssl3HelloExtensionHandler serverHelloHandlersSSL3[] = {
2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { ssl_renegotiation_info_xtn, &ssl3_HandleRenegotiationInfoXtn },
2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { -1, NULL }
2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* Tables of functions to format TLS hello extensions, one function per
2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * extension.
2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * These static tables are for the formatting of client hello extensions.
2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * The server's table of hello senders is dynamic, in the socket struct,
2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * and sender functions are registered there.
2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const
2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ssl3HelloExtensionSender clientHelloSendersTLS[SSL_MAX_EXTENSIONS] = {
286eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    { ssl_server_name_xtn,            &ssl3_SendServerNameXtn        },
287eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    { ssl_renegotiation_info_xtn,     &ssl3_SendRenegotiationInfoXtn },
2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef NSS_ENABLE_ECC
289eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    { ssl_elliptic_curves_xtn,        &ssl3_SendSupportedCurvesXtn },
290eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    { ssl_ec_point_formats_xtn,       &ssl3_SendSupportedPointFormatsXtn },
2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
292eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    { ssl_session_ticket_xtn,         &ssl3_SendSessionTicketXtn },
293eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    { ssl_next_proto_nego_xtn,        &ssl3_ClientSendNextProtoNegoXtn },
294a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    { ssl_app_layer_protocol_xtn,     &ssl3_ClientSendAppProtoXtn },
295eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    { ssl_use_srtp_xtn,               &ssl3_SendUseSRTPXtn },
296eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    { ssl_channel_id_xtn,             &ssl3_ClientSendChannelIDXtn },
297eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    { ssl_cert_status_xtn,            &ssl3_ClientSendStatusRequestXtn },
298f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    { ssl_signature_algorithms_xtn,   &ssl3_ClientSendSigAlgsXtn },
299f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    { ssl_signed_certificate_timestamp_xtn,
300f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      &ssl3_ClientSendSignedCertTimestampXtn }
3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /* any extra entries will appear as { 0, NULL }    */
3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const
3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ssl3HelloExtensionSender clientHelloSendersSSL3[SSL_MAX_EXTENSIONS] = {
3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { ssl_renegotiation_info_xtn, &ssl3_SendRenegotiationInfoXtn }
3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /* any extra entries will appear as { 0, NULL }    */
3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static PRBool
3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)arrayContainsExtension(const PRUint16 *array, PRUint32 len, PRUint16 ex_type)
3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int i;
3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for (i = 0; i < len; i++) {
3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (ex_type == array[i])
3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    return PR_TRUE;
3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return PR_FALSE;
3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PRBool
3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ssl3_ExtensionNegotiated(sslSocket *ss, PRUint16 ex_type) {
3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    TLSExtensionData *xtnData = &ss->xtnData;
3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return arrayContainsExtension(xtnData->negotiated,
3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	                          xtnData->numNegotiated, ex_type);
3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static PRBool
3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ssl3_ClientExtensionAdvertised(sslSocket *ss, PRUint16 ex_type) {
3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    TLSExtensionData *xtnData = &ss->xtnData;
3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return arrayContainsExtension(xtnData->advertised,
3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	                          xtnData->numAdvertised, ex_type);
3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* Format an SNI extension, using the name from the socket's URL,
3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * unless that name is a dotted decimal string.
3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Used by client and server.
3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PRInt32
3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ssl3_SendServerNameXtn(sslSocket * ss, PRBool append,
3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       PRUint32 maxBytes)
3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SECStatus rv;
3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!ss)
3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    	return 0;
3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!ss->sec.isServer) {
3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        PRUint32 len;
3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        PRNetAddr netAddr;
3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        /* must have a hostname */
3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if (!ss->url || !ss->url[0])
3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            return 0;
3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        /* must not be an IPv4 or IPv6 address */
3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if (PR_SUCCESS == PR_StringToNetAddr(ss->url, &netAddr)) {
3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            /* is an IP address (v4 or v6) */
3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            return 0;
3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        len  = PORT_Strlen(ss->url);
3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if (append && maxBytes >= len + 9) {
3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            /* extension_type */
3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            rv = ssl3_AppendHandshakeNumber(ss, ssl_server_name_xtn, 2);
3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            if (rv != SECSuccess) return -1;
3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            /* length of extension_data */
3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            rv = ssl3_AppendHandshakeNumber(ss, len + 5, 2);
3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            if (rv != SECSuccess) return -1;
3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            /* length of server_name_list */
3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            rv = ssl3_AppendHandshakeNumber(ss, len + 3, 2);
3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            if (rv != SECSuccess) return -1;
3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            /* Name Type (sni_host_name) */
3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            rv = ssl3_AppendHandshake(ss,       "\0",    1);
3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            if (rv != SECSuccess) return -1;
3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            /* HostName (length and value) */
3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            rv = ssl3_AppendHandshakeVariable(ss, (PRUint8 *)ss->url, len, 2);
3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            if (rv != SECSuccess) return -1;
3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            if (!ss->sec.isServer) {
3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                TLSExtensionData *xtnData = &ss->xtnData;
3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                xtnData->advertised[xtnData->numAdvertised++] =
3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    ssl_server_name_xtn;
3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            }
3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return len + 9;
3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /* Server side */
3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (append && maxBytes >= 4) {
3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        rv = ssl3_AppendHandshakeNumber(ss, ssl_server_name_xtn, 2);
3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if (rv != SECSuccess)  return -1;
3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        /* length of extension_data */
3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        rv = ssl3_AppendHandshakeNumber(ss, 0, 2);
3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if (rv != SECSuccess) return -1;
3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return 4;
3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* handle an incoming SNI extension, by ignoring it. */
3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SECStatus
3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ssl3_HandleServerNameXtn(sslSocket * ss, PRUint16 ex_type, SECItem *data)
3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SECItem *names = NULL;
3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PRUint32 listCount = 0, namesPos = 0, i;
4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    TLSExtensionData *xtnData = &ss->xtnData;
4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SECItem  ldata;
4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PRInt32  listLenBytes = 0;
4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!ss->sec.isServer) {
4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        /* Verify extension_data is empty. */
4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if (data->data || data->len ||
4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            !ssl3_ExtensionNegotiated(ss, ssl_server_name_xtn)) {
4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            /* malformed or was not initiated by the client.*/
4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            return SECFailure;
4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return SECSuccess;
4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /* Server side - consume client data and register server sender. */
4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /* do not parse the data if don't have user extension handling function. */
4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!ss->sniSocketConfig) {
4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return SECSuccess;
4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /* length of server_name_list */
4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    listLenBytes = ssl3_ConsumeHandshakeNumber(ss, 2, &data->data, &data->len);
4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (listLenBytes == 0 || listLenBytes != data->len) {
4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return SECFailure;
4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ldata = *data;
4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /* Calculate the size of the array.*/
4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    while (listLenBytes > 0) {
4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        SECItem litem;
4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        SECStatus rv;
4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        PRInt32  type;
4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        /* Name Type (sni_host_name) */
4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        type = ssl3_ConsumeHandshakeNumber(ss, 1, &ldata.data, &ldata.len);
4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if (!ldata.len) {
4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            return SECFailure;
4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        rv = ssl3_ConsumeHandshakeVariable(ss, &litem, 2, &ldata.data, &ldata.len);
4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if (rv != SECSuccess) {
4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            return SECFailure;
4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        /* Adjust total length for cunsumed item, item len and type.*/
4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        listLenBytes -= litem.len + 3;
4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if (listLenBytes > 0 && !ldata.len) {
4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            return SECFailure;
4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        listCount += 1;
4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!listCount) {
4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return SECFailure;
4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    names = PORT_ZNewArray(SECItem, listCount);
4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!names) {
4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return SECFailure;
4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for (i = 0;i < listCount;i++) {
4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        int j;
4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        PRInt32  type;
4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        SECStatus rv;
4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        PRBool nametypePresent = PR_FALSE;
4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        /* Name Type (sni_host_name) */
4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        type = ssl3_ConsumeHandshakeNumber(ss, 1, &data->data, &data->len);
4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        /* Check if we have such type in the list */
4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        for (j = 0;j < listCount && names[j].data;j++) {
4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            if (names[j].type == type) {
4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                nametypePresent = PR_TRUE;
4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                break;
4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            }
4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        /* HostName (length and value) */
4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        rv = ssl3_ConsumeHandshakeVariable(ss, &names[namesPos], 2,
4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                           &data->data, &data->len);
4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if (rv != SECSuccess) {
4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            goto loser;
4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if (nametypePresent == PR_FALSE) {
4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            namesPos += 1;
4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
4765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
4775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /* Free old and set the new data. */
4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (xtnData->sniNameArr) {
4795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        PORT_Free(ss->xtnData.sniNameArr);
4805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
4815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xtnData->sniNameArr = names;
4825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xtnData->sniNameArrSize = namesPos;
4835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xtnData->negotiated[xtnData->numNegotiated++] = ssl_server_name_xtn;
4845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return SECSuccess;
4865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)loser:
4885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PORT_Free(names);
4895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return SECFailure;
4905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* Called by both clients and servers.
4935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Clients sends a filled in session ticket if one is available, and otherwise
4945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * sends an empty ticket.  Servers always send empty tickets.
4955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
4965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PRInt32
4975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ssl3_SendSessionTicketXtn(
4985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			sslSocket * ss,
4995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			PRBool      append,
5005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			PRUint32    maxBytes)
5015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
5025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PRInt32 extension_length;
5035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    NewSessionTicket *session_ticket = NULL;
5045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /* Ignore the SessionTicket extension if processing is disabled. */
5065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!ss->opt.enableSessionTickets)
5075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return 0;
5085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /* Empty extension length = extension_type (2-bytes) +
5105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * length(extension_data) (2-bytes)
5115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     */
5125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    extension_length = 4;
5135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /* If we are a client then send a session ticket if one is availble.
5155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * Servers that support the extension and are willing to negotiate the
5165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * the extension always respond with an empty extension.
5175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     */
5185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!ss->sec.isServer) {
5195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	sslSessionID *sid = ss->sec.ci.sid;
5205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	session_ticket = &sid->u.ssl3.sessionTicket;
5215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (session_ticket->ticket.data) {
5225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    if (ss->xtnData.ticketTimestampVerified) {
5235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		extension_length += session_ticket->ticket.len;
5245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    } else if (!append &&
5255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		(session_ticket->ticket_lifetime_hint == 0 ||
5265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		(session_ticket->ticket_lifetime_hint +
5275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    session_ticket->received_timestamp > ssl_Time()))) {
5285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		extension_length += session_ticket->ticket.len;
5295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		ss->xtnData.ticketTimestampVerified = PR_TRUE;
5305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    }
5315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
5325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
5335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (append && maxBytes >= extension_length) {
5355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	SECStatus rv;
5365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/* extension_type */
5375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        rv = ssl3_AppendHandshakeNumber(ss, ssl_session_ticket_xtn, 2);
5385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if (rv != SECSuccess)
5395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    goto loser;
5405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (session_ticket && session_ticket->ticket.data &&
5415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    ss->xtnData.ticketTimestampVerified) {
5425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    rv = ssl3_AppendHandshakeVariable(ss, session_ticket->ticket.data,
5435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		session_ticket->ticket.len, 2);
5445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    ss->xtnData.ticketTimestampVerified = PR_FALSE;
5455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	} else {
5465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    rv = ssl3_AppendHandshakeNumber(ss, 0, 2);
5475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
5485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if (rv != SECSuccess)
5495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    goto loser;
5505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (!ss->sec.isServer) {
5525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    TLSExtensionData *xtnData = &ss->xtnData;
5535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    xtnData->advertised[xtnData->numAdvertised++] =
5545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		ssl_session_ticket_xtn;
5555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
5565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else if (maxBytes < extension_length) {
5575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	PORT_Assert(0);
5585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return 0;
5595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
5605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return extension_length;
5615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) loser:
5635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ss->xtnData.ticketTimestampVerified = PR_FALSE;
5645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return -1;
5655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* handle an incoming Next Protocol Negotiation extension. */
5685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static SECStatus
5695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ssl3_ServerHandleNextProtoNegoXtn(sslSocket * ss, PRUint16 ex_type, SECItem *data)
5705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
5715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (ss->firstHsDone || data->len != 0) {
5725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/* Clients MUST send an empty NPN extension, if any. */
5735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	PORT_SetError(SSL_ERROR_NEXT_PROTOCOL_DATA_INVALID);
5745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return SECFailure;
5755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
5765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ss->xtnData.negotiated[ss->xtnData.numNegotiated++] = ex_type;
5785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /* TODO: server side NPN support would require calling
5805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * ssl3_RegisterServerHelloExtensionSender here in order to echo the
5815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * extension back to the client. */
5825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return SECSuccess;
5845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* ssl3_ValidateNextProtoNego checks that the given block of data is valid: none
5875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * of the lengths may be 0 and the sum of the lengths must equal the length of
5885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * the block. */
5895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SECStatus
5905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ssl3_ValidateNextProtoNego(const unsigned char* data, unsigned int length)
5915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
5925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    unsigned int offset = 0;
5935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    while (offset < length) {
5955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	unsigned int newOffset = offset + 1 + (unsigned int) data[offset];
5965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/* Reject embedded nulls to protect against buggy applications that
5975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	 * store protocol identifiers in null-terminated strings.
5985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	 */
5995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (newOffset > length || data[offset] == 0) {
6005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    PORT_SetError(SSL_ERROR_NEXT_PROTOCOL_DATA_INVALID);
6015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    return SECFailure;
6025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
6035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	offset = newOffset;
6045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
6055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (offset > length) {
6075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	PORT_SetError(SSL_ERROR_NEXT_PROTOCOL_DATA_INVALID);
6085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return SECFailure;
6095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
6105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return SECSuccess;
6125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static SECStatus
6155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ssl3_ClientHandleNextProtoNegoXtn(sslSocket *ss, PRUint16 ex_type,
6165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				  SECItem *data)
6175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
6185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SECStatus rv;
6195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    unsigned char resultBuffer[255];
6205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SECItem result = { siBuffer, resultBuffer, 0 };
6215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PORT_Assert(!ss->firstHsDone);
6235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
624a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    if (ssl3_ExtensionNegotiated(ss, ssl_app_layer_protocol_xtn)) {
625eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch	PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
626eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch	return SECFailure;
627eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    }
628eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
6295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rv = ssl3_ValidateNextProtoNego(data->data, data->len);
6305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (rv != SECSuccess)
6315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return rv;
6325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /* ss->nextProtoCallback cannot normally be NULL if we negotiated the
6345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * extension. However, It is possible that an application erroneously
6355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * cleared the callback between the time we sent the ClientHello and now.
6365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     */
6375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PORT_Assert(ss->nextProtoCallback != NULL);
6385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!ss->nextProtoCallback) {
6395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/* XXX Use a better error code. This is an application error, not an
6405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	 * NSS bug. */
6415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
6425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return SECFailure;
6435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
6445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rv = ss->nextProtoCallback(ss->nextProtoArg, ss->fd, data->data, data->len,
6465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			       result.data, &result.len, sizeof resultBuffer);
6475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (rv != SECSuccess)
6485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return rv;
6495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /* If the callback wrote more than allowed to |result| it has corrupted our
6505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * stack. */
6515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (result.len > sizeof resultBuffer) {
6525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	PORT_SetError(SEC_ERROR_OUTPUT_LEN);
6535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return SECFailure;
6545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
6555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ss->xtnData.negotiated[ss->xtnData.numNegotiated++] = ex_type;
6575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SECITEM_FreeItem(&ss->ssl3.nextProto, PR_FALSE);
6595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return SECITEM_CopyItem(NULL, &ss->ssl3.nextProto, &result);
6605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
662eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochstatic SECStatus
663eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochssl3_ClientHandleAppProtoXtn(sslSocket *ss, PRUint16 ex_type, SECItem *data)
664eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch{
665eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    const unsigned char* d = data->data;
666eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    PRUint16 name_list_len;
667eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    SECItem protocol_name;
668eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
669eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    if (ssl3_ExtensionNegotiated(ss, ssl_next_proto_nego_xtn)) {
670eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch	PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
671eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch	return SECFailure;
672eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    }
673eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
674eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    /* The extension data from the server has the following format:
675eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch     *   uint16 name_list_len;
676eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch     *   uint8 len;
677eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch     *   uint8 protocol_name[len]; */
678eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    if (data->len < 4 || data->len > 2 + 1 + 255) {
679eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch	PORT_SetError(SSL_ERROR_NEXT_PROTOCOL_DATA_INVALID);
680eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch	return SECFailure;
681eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    }
682eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
683eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    name_list_len = ((PRUint16) d[0]) << 8 |
684eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch	            ((PRUint16) d[1]);
685eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    if (name_list_len != data->len - 2 ||
686eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch	d[2] != data->len - 3) {
687eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch	PORT_SetError(SSL_ERROR_NEXT_PROTOCOL_DATA_INVALID);
688eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch	return SECFailure;
689eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    }
690eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
691eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    protocol_name.data = data->data + 3;
692eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    protocol_name.len = data->len - 3;
693eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
694eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    SECITEM_FreeItem(&ss->ssl3.nextProto, PR_FALSE);
695eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    ss->ssl3.nextProtoState = SSL_NEXT_PROTO_SELECTED;
696eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    ss->xtnData.negotiated[ss->xtnData.numNegotiated++] = ex_type;
697eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    return SECITEM_CopyItem(NULL, &ss->ssl3.nextProto, &protocol_name);
698eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
699eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
7005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static PRInt32
7015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ssl3_ClientSendNextProtoNegoXtn(sslSocket * ss, PRBool append,
7025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				PRUint32 maxBytes)
7035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
7045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PRInt32 extension_length;
7055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /* Renegotiations do not send this extension. */
7075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!ss->nextProtoCallback || ss->firstHsDone) {
7085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return 0;
7095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
7105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    extension_length = 4;
7125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (append && maxBytes >= extension_length) {
7145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	SECStatus rv;
7155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	rv = ssl3_AppendHandshakeNumber(ss, ssl_next_proto_nego_xtn, 2);
7165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (rv != SECSuccess)
7175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    goto loser;
7185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	rv = ssl3_AppendHandshakeNumber(ss, 0, 2);
7195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (rv != SECSuccess)
7205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    goto loser;
7215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ss->xtnData.advertised[ss->xtnData.numAdvertised++] =
7225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		ssl_next_proto_nego_xtn;
7235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else if (maxBytes < extension_length) {
7245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return 0;
7255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
7265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return extension_length;
7285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)loser:
7305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return -1;
7315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
733eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochstatic PRInt32
734eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochssl3_ClientSendAppProtoXtn(sslSocket * ss, PRBool append, PRUint32 maxBytes)
735eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch{
736eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    PRInt32 extension_length;
737ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    unsigned char *alpn_protos = NULL;
738eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
739eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    /* Renegotiations do not send this extension. */
740eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    if (!ss->opt.nextProtoNego.data || ss->firstHsDone) {
741eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch	return 0;
742eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    }
743eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
744eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    extension_length = 2 /* extension type */ + 2 /* extension length */ +
745eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                       2 /* protocol name list length */ +
746eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                       ss->opt.nextProtoNego.len;
747eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
748eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    if (append && maxBytes >= extension_length) {
749ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch	/* NPN requires that the client's fallback protocol is first in the
750ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch	 * list. However, ALPN sends protocols in preference order. So we
751ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch	 * allocate a buffer and move the first protocol to the end of the
752ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch	 * list. */
753eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch	SECStatus rv;
754ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch	const unsigned int len = ss->opt.nextProtoNego.len;
755ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
756ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch	alpn_protos = PORT_Alloc(len);
757ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch	if (alpn_protos == NULL) {
758ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch	    return SECFailure;
759ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch	}
760ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch	if (len > 0) {
761ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch	    /* Each protocol string is prefixed with a single byte length. */
762ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch	    unsigned int i = ss->opt.nextProtoNego.data[0] + 1;
763ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch	    if (i <= len) {
764ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch		memcpy(alpn_protos, &ss->opt.nextProtoNego.data[i], len - i);
765ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch		memcpy(alpn_protos + len - i, ss->opt.nextProtoNego.data, i);
766ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch	    } else {
767ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch		/* This seems to be invalid data so we'll send as-is. */
768ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch		memcpy(alpn_protos, ss->opt.nextProtoNego.data, len);
769ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch	    }
770ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch	}
771ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
772a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)	rv = ssl3_AppendHandshakeNumber(ss, ssl_app_layer_protocol_xtn, 2);
773eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch	if (rv != SECSuccess)
774eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch	    goto loser;
775eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch	rv = ssl3_AppendHandshakeNumber(ss, extension_length - 4, 2);
776eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch	if (rv != SECSuccess)
777eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch	    goto loser;
778ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch	rv = ssl3_AppendHandshakeVariable(ss, alpn_protos, len, 2);
779ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch	PORT_Free(alpn_protos);
780ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch	alpn_protos = NULL;
781eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch	if (rv != SECSuccess)
782eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch	    goto loser;
783eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch	ss->xtnData.advertised[ss->xtnData.numAdvertised++] =
784a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)		ssl_app_layer_protocol_xtn;
785eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    } else if (maxBytes < extension_length) {
786eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch	return 0;
787eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    }
788eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
789eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    return extension_length;
790eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
791eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochloser:
792ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    if (alpn_protos)
793ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch	PORT_Free(alpn_protos);
794eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    return -1;
795eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
796eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
7975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static SECStatus
7985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ssl3_ClientHandleChannelIDXtn(sslSocket *ss, PRUint16 ex_type,
7995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			     SECItem *data)
8005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
8015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PORT_Assert(ss->getChannelID != NULL);
8025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (data->len) {
8045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	PORT_SetError(SSL_ERROR_BAD_CHANNEL_ID_DATA);
8055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return SECFailure;
8065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
8075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ss->xtnData.negotiated[ss->xtnData.numNegotiated++] = ex_type;
8085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return SECSuccess;
8095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static PRInt32
8125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ssl3_ClientSendChannelIDXtn(sslSocket * ss, PRBool append,
8135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			    PRUint32 maxBytes)
8145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
8155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PRInt32 extension_length = 4;
8165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!ss->getChannelID)
8185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return 0;
8195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (maxBytes < extension_length) {
8215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	PORT_Assert(0);
8225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return 0;
8235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
8245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
825f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    if (ss->sec.ci.sid->cached != never_cached &&
826f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        ss->sec.ci.sid->u.ssl3.originalHandshakeHash.len == 0) {
827f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        /* We can't do ChannelID on a connection if we're resuming and didn't
828f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)         * do ChannelID on the original connection: without ChannelID on the
829f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)         * original connection we didn't record the handshake hashes needed for
830f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)         * the signature. */
831f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)	return 0;
832f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    }
833f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
8345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (append) {
8355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	SECStatus rv;
8365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	rv = ssl3_AppendHandshakeNumber(ss, ssl_channel_id_xtn, 2);
8375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (rv != SECSuccess)
8385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    goto loser;
8395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	rv = ssl3_AppendHandshakeNumber(ss, 0, 2);
8405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (rv != SECSuccess)
8415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    goto loser;
8425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ss->xtnData.advertised[ss->xtnData.numAdvertised++] =
8435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		ssl_channel_id_xtn;
8445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
8455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return extension_length;
8475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)loser:
8495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return -1;
8505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
852c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)static SECStatus
8535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ssl3_ClientHandleStatusRequestXtn(sslSocket *ss, PRUint16 ex_type,
854c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                 SECItem *data)
8555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
8565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /* The echoed extension must be empty. */
8575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (data->len != 0)
858c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)       return SECFailure;
8595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /* Keep track of negotiated extensions. */
8615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ss->xtnData.negotiated[ss->xtnData.numNegotiated++] = ex_type;
8625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return SECSuccess;
8645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
866c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)static PRInt32
867c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)ssl3_ServerSendStatusRequestXtn(
868c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)			sslSocket * ss,
869c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)			PRBool      append,
870c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)			PRUint32    maxBytes)
871c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles){
872c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    PRInt32 extension_length;
873c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    SECStatus rv;
874a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    int i;
875a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    PRBool haveStatus = PR_FALSE;
876c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
877a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    for (i = kt_null; i < kt_kea_size; i++) {
878a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)	/* TODO: This is a temporary workaround.
879a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)	 *       The correct code needs to see if we have an OCSP response for
880a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)	 *       the server certificate being used, rather than if we have any
881a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)	 *       OCSP response. See also ssl3_SendCertificateStatus.
882a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)	 */
883a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)	if (ss->certStatusArray[i] && ss->certStatusArray[i]->len) {
884a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)	    haveStatus = PR_TRUE;
885a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)	    break;
886a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)	}
887a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    }
888a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    if (!haveStatus)
889c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)	return 0;
890c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
891c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    extension_length = 2 + 2;
892c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    if (append && maxBytes >= extension_length) {
893c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)	/* extension_type */
894c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)	rv = ssl3_AppendHandshakeNumber(ss, ssl_cert_status_xtn, 2);
895c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)	if (rv != SECSuccess)
896c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)	    return -1;
897c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)	/* length of extension_data */
898c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)	rv = ssl3_AppendHandshakeNumber(ss, 0, 2);
899c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)	if (rv != SECSuccess)
900c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)	    return -1;
901c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    }
902c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
903c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return extension_length;
904c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
905c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
9065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* ssl3_ClientSendStatusRequestXtn builds the status_request extension on the
9075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * client side. See RFC 4366 section 3.6. */
908c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)static PRInt32
9095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ssl3_ClientSendStatusRequestXtn(sslSocket * ss, PRBool append,
910c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                               PRUint32 maxBytes)
9115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
9125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PRInt32 extension_length;
9135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!ss->opt.enableOCSPStapling)
915c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)       return 0;
9165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /* extension_type (2-bytes) +
9185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * length(extension_data) (2-bytes) +
9195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * status_type (1) +
9205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * responder_id_list length (2) +
9215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * request_extensions length (2)
9225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     */
9235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    extension_length = 9;
9245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (append && maxBytes >= extension_length) {
926c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)       SECStatus rv;
927c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)       TLSExtensionData *xtnData;
928c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
929c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)       /* extension_type */
930c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)       rv = ssl3_AppendHandshakeNumber(ss, ssl_cert_status_xtn, 2);
931c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)       if (rv != SECSuccess)
932c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)           return -1;
933c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)       rv = ssl3_AppendHandshakeNumber(ss, extension_length - 4, 2);
934c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)       if (rv != SECSuccess)
935c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)           return -1;
936c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)       rv = ssl3_AppendHandshakeNumber(ss, 1 /* status_type ocsp */, 1);
937c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)       if (rv != SECSuccess)
938c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)           return -1;
939c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)       /* A zero length responder_id_list means that the responders are
940c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        * implicitly known to the server. */
941c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)       rv = ssl3_AppendHandshakeNumber(ss, 0, 2);
942c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)       if (rv != SECSuccess)
943c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)           return -1;
944c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)       /* A zero length request_extensions means that there are no extensions.
945c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        * Specifically, we don't set the id-pkix-ocsp-nonce extension. This
946c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        * means that the server can replay a cached OCSP response to us. */
947c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)       rv = ssl3_AppendHandshakeNumber(ss, 0, 2);
948c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)       if (rv != SECSuccess)
949c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)           return -1;
950c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
951c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)       xtnData = &ss->xtnData;
952c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)       xtnData->advertised[xtnData->numAdvertised++] = ssl_cert_status_xtn;
9535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else if (maxBytes < extension_length) {
954c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)       PORT_Assert(0);
955c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)       return 0;
9565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
9575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return extension_length;
9585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
9615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * NewSessionTicket
9625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Called from ssl3_HandleFinished
9635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
9645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SECStatus
9655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ssl3_SendNewSessionTicket(sslSocket *ss)
9665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
9675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int                  i;
9685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SECStatus            rv;
9695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    NewSessionTicket     ticket;
9705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SECItem              plaintext;
9715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SECItem              plaintext_item = {0, NULL, 0};
9725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SECItem              ciphertext     = {0, NULL, 0};
9735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PRUint32             ciphertext_length;
9745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PRBool               ms_is_wrapped;
9755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    unsigned char        wrapped_ms[SSL3_MASTER_SECRET_LENGTH];
9765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SECItem              ms_item = {0, NULL, 0};
9775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SSL3KEAType          effectiveExchKeyType = ssl_kea_null;
9785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PRUint32             padding_length;
9795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PRUint32             message_length;
9805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PRUint32             cert_length;
981a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    PRUint8              length_buf[4];
9825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PRUint32             now;
9835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PK11SymKey          *aes_key_pkcs11;
9845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PK11SymKey          *mac_key_pkcs11;
9852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#ifndef NO_PKCS11_BYPASS
9865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const unsigned char *aes_key;
9875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const unsigned char *mac_key;
9885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PRUint32             aes_key_length;
9895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PRUint32             mac_key_length;
9905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PRUint64             aes_ctx_buf[MAX_CIPHER_CONTEXT_LLONGS];
9915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    AESContext          *aes_ctx;
9925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const SECHashObject *hashObj = NULL;
9935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PRUint64             hmac_ctx_buf[MAX_MAC_CONTEXT_LLONGS];
9945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    HMACContext         *hmac_ctx;
9952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif
9962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    CK_MECHANISM_TYPE    cipherMech = CKM_AES_CBC;
9972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    PK11Context         *aes_ctx_pkcs11;
9985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CK_MECHANISM_TYPE    macMech = CKM_SHA256_HMAC;
9995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PK11Context         *hmac_ctx_pkcs11;
10005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    unsigned char        computed_mac[TLS_EX_SESS_TICKET_MAC_LENGTH];
10015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    unsigned int         computed_mac_length;
10025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    unsigned char        iv[AES_BLOCK_SIZE];
10035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SECItem              ivItem;
10045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SECItem             *srvName = NULL;
10055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PRUint32             srvNameLen = 0;
10065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CK_MECHANISM_TYPE    msWrapMech = 0; /* dummy default value,
10075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                          * must be >= 0 */
10085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SSL_TRC(3, ("%d: SSL3[%d]: send session_ticket handshake",
10105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		SSL_GETPID(), ss->fd));
10115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PORT_Assert( ss->opt.noLocks || ssl_HaveXmitBufLock(ss));
10135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss));
10145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ticket.ticket_lifetime_hint = TLS_EX_SESS_TICKET_LIFETIME_HINT;
10165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    cert_length = (ss->opt.requestCertificate && ss->sec.ci.sid->peerCert) ?
10175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	3 + ss->sec.ci.sid->peerCert->derCert.len : 0;
10185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /* Get IV and encryption keys */
10205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ivItem.data = iv;
10215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ivItem.len = sizeof(iv);
10225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rv = PK11_GenerateRandom(iv, sizeof(iv));
10235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (rv != SECSuccess) goto loser;
10245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#ifndef NO_PKCS11_BYPASS
10265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (ss->opt.bypassPKCS11) {
10275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	rv = ssl3_GetSessionTicketKeys(&aes_key, &aes_key_length,
10285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    &mac_key, &mac_key_length);
10292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    } else
10302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif
10312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    {
10325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	rv = ssl3_GetSessionTicketKeysPKCS11(ss, &aes_key_pkcs11,
10335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    &mac_key_pkcs11);
10345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
10355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (rv != SECSuccess) goto loser;
10365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (ss->ssl3.pwSpec->msItem.len && ss->ssl3.pwSpec->msItem.data) {
10385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/* The master secret is available unwrapped. */
10395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ms_item.data = ss->ssl3.pwSpec->msItem.data;
10405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ms_item.len = ss->ssl3.pwSpec->msItem.len;
10415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ms_is_wrapped = PR_FALSE;
10425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else {
10435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/* Extract the master secret wrapped. */
10445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	sslSessionID sid;
10455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	PORT_Memset(&sid, 0, sizeof(sslSessionID));
10465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (ss->ssl3.hs.kea_def->kea == kea_ecdhe_rsa) {
10485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    effectiveExchKeyType = kt_rsa;
10495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	} else {
10505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    effectiveExchKeyType = ss->ssl3.hs.kea_def->exchKeyType;
10515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
10525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	rv = ssl3_CacheWrappedMasterSecret(ss, &sid, ss->ssl3.pwSpec,
10545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    effectiveExchKeyType);
10555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (rv == SECSuccess) {
10565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    if (sid.u.ssl3.keys.wrapped_master_secret_len > sizeof(wrapped_ms))
10575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		goto loser;
10585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    memcpy(wrapped_ms, sid.u.ssl3.keys.wrapped_master_secret,
10595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		sid.u.ssl3.keys.wrapped_master_secret_len);
10605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    ms_item.data = wrapped_ms;
10615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    ms_item.len = sid.u.ssl3.keys.wrapped_master_secret_len;
10625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    msWrapMech = sid.u.ssl3.masterWrapMech;
10635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	} else {
10645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    /* TODO: else send an empty ticket. */
10655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    goto loser;
10665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
10675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ms_is_wrapped = PR_TRUE;
10685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
10695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /* Prep to send negotiated name */
10705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    srvName = &ss->ssl3.pwSpec->srvVirtName;
10715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (srvName->data && srvName->len) {
10725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        srvNameLen = 2 + srvName->len; /* len bytes + name len */
10735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
10745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ciphertext_length =
10765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	sizeof(PRUint16)                     /* ticket_version */
10775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	+ sizeof(SSL3ProtocolVersion)        /* ssl_version */
10785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	+ sizeof(ssl3CipherSuite)            /* ciphersuite */
10795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	+ 1                                  /* compression */
10805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	+ 10                                 /* cipher spec parameters */
10815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	+ 1                                  /* SessionTicket.ms_is_wrapped */
10825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	+ 1                                  /* effectiveExchKeyType */
10835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	+ 4                                  /* msWrapMech */
10845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	+ 2                                  /* master_secret.length */
10855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	+ ms_item.len                        /* master_secret */
10865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	+ 1                                  /* client_auth_type */
10875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	+ cert_length                        /* cert */
10885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        + 1                                  /* server name type */
10895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        + srvNameLen                         /* name len + length field */
10905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	+ sizeof(ticket.ticket_lifetime_hint);
10915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    padding_length =  AES_BLOCK_SIZE -
10925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	(ciphertext_length % AES_BLOCK_SIZE);
10935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ciphertext_length += padding_length;
10945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    message_length =
10965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	sizeof(ticket.ticket_lifetime_hint)    /* ticket_lifetime_hint */
10975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	+ 2 /* length field for NewSessionTicket.ticket */
10985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	+ SESS_TICKET_KEY_NAME_LEN             /* key_name */
10995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	+ AES_BLOCK_SIZE                       /* iv */
11005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	+ 2 /* length field for NewSessionTicket.ticket.encrypted_state */
11015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	+ ciphertext_length                    /* encrypted_state */
11025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	+ TLS_EX_SESS_TICKET_MAC_LENGTH;       /* mac */
11035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (SECITEM_AllocItem(NULL, &plaintext_item, ciphertext_length) == NULL)
11055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	goto loser;
11065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    plaintext = plaintext_item;
11085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /* ticket_version */
11105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rv = ssl3_AppendNumberToItem(&plaintext, TLS_EX_SESS_TICKET_VERSION,
11115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	sizeof(PRUint16));
11125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (rv != SECSuccess) goto loser;
11135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /* ssl_version */
11155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rv = ssl3_AppendNumberToItem(&plaintext, ss->version,
11165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	sizeof(SSL3ProtocolVersion));
11175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (rv != SECSuccess) goto loser;
11185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /* ciphersuite */
11205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rv = ssl3_AppendNumberToItem(&plaintext, ss->ssl3.hs.cipher_suite,
11215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	sizeof(ssl3CipherSuite));
11225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (rv != SECSuccess) goto loser;
11235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /* compression */
11255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rv = ssl3_AppendNumberToItem(&plaintext, ss->ssl3.hs.compression, 1);
11265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (rv != SECSuccess) goto loser;
11275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /* cipher spec parameters */
11295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rv = ssl3_AppendNumberToItem(&plaintext, ss->sec.authAlgorithm, 1);
11305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (rv != SECSuccess) goto loser;
11315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rv = ssl3_AppendNumberToItem(&plaintext, ss->sec.authKeyBits, 4);
11325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (rv != SECSuccess) goto loser;
11335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rv = ssl3_AppendNumberToItem(&plaintext, ss->sec.keaType, 1);
11345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (rv != SECSuccess) goto loser;
11355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rv = ssl3_AppendNumberToItem(&plaintext, ss->sec.keaKeyBits, 4);
11365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (rv != SECSuccess) goto loser;
11375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /* master_secret */
11395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rv = ssl3_AppendNumberToItem(&plaintext, ms_is_wrapped, 1);
11405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (rv != SECSuccess) goto loser;
11415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rv = ssl3_AppendNumberToItem(&plaintext, effectiveExchKeyType, 1);
11425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (rv != SECSuccess) goto loser;
11435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rv = ssl3_AppendNumberToItem(&plaintext, msWrapMech, 4);
11445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (rv != SECSuccess) goto loser;
11455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rv = ssl3_AppendNumberToItem(&plaintext, ms_item.len, 2);
11465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (rv != SECSuccess) goto loser;
11475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rv = ssl3_AppendToItem(&plaintext, ms_item.data, ms_item.len);
11485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (rv != SECSuccess) goto loser;
11495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /* client_identity */
11515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (ss->opt.requestCertificate && ss->sec.ci.sid->peerCert) {
11525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	rv = ssl3_AppendNumberToItem(&plaintext, CLIENT_AUTH_CERTIFICATE, 1);
11535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (rv != SECSuccess) goto loser;
11545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	rv = ssl3_AppendNumberToItem(&plaintext,
11555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    ss->sec.ci.sid->peerCert->derCert.len, 3);
11565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (rv != SECSuccess) goto loser;
11575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	rv = ssl3_AppendToItem(&plaintext,
11585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    ss->sec.ci.sid->peerCert->derCert.data,
11595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    ss->sec.ci.sid->peerCert->derCert.len);
11605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (rv != SECSuccess) goto loser;
11615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else {
11625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	rv = ssl3_AppendNumberToItem(&plaintext, 0, 1);
11635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (rv != SECSuccess) goto loser;
11645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
11655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /* timestamp */
11675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    now = ssl_Time();
11685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rv = ssl3_AppendNumberToItem(&plaintext, now,
11695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	sizeof(ticket.ticket_lifetime_hint));
11705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (rv != SECSuccess) goto loser;
11715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (srvNameLen) {
11735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        /* Name Type (sni_host_name) */
11745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        rv = ssl3_AppendNumberToItem(&plaintext, srvName->type, 1);
11755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if (rv != SECSuccess) goto loser;
11765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        /* HostName (length and value) */
11775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        rv = ssl3_AppendNumberToItem(&plaintext, srvName->len, 2);
11785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if (rv != SECSuccess) goto loser;
11795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        rv = ssl3_AppendToItem(&plaintext, srvName->data, srvName->len);
11805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if (rv != SECSuccess) goto loser;
11815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else {
11825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        /* No Name */
11835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        rv = ssl3_AppendNumberToItem(&plaintext, (char)TLS_STE_NO_SERVER_NAME,
11845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                     1);
11855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if (rv != SECSuccess) goto loser;
11865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
11875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PORT_Assert(plaintext.len == padding_length);
11895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for (i = 0; i < padding_length; i++)
11905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	plaintext.data[i] = (unsigned char)padding_length;
11915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (SECITEM_AllocItem(NULL, &ciphertext, ciphertext_length) == NULL) {
11935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	rv = SECFailure;
11945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	goto loser;
11955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
11965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /* Generate encrypted portion of ticket. */
11982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#ifndef NO_PKCS11_BYPASS
11995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (ss->opt.bypassPKCS11) {
12005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	aes_ctx = (AESContext *)aes_ctx_buf;
12015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	rv = AES_InitContext(aes_ctx, aes_key, aes_key_length, iv,
12025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    NSS_AES_CBC, 1, AES_BLOCK_SIZE);
12035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (rv != SECSuccess) goto loser;
12045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	rv = AES_Encrypt(aes_ctx, ciphertext.data, &ciphertext.len,
12065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    ciphertext.len, plaintext_item.data,
12075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    plaintext_item.len);
12085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (rv != SECSuccess) goto loser;
12092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    } else
12102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif
12112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    {
12125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	aes_ctx_pkcs11 = PK11_CreateContextBySymKey(cipherMech,
12135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    CKA_ENCRYPT, aes_key_pkcs11, &ivItem);
12145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (!aes_ctx_pkcs11)
12155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    goto loser;
12165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	rv = PK11_CipherOp(aes_ctx_pkcs11, ciphertext.data,
12185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    (int *)&ciphertext.len, ciphertext.len,
12195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    plaintext_item.data, plaintext_item.len);
12205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	PK11_Finalize(aes_ctx_pkcs11);
12215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	PK11_DestroyContext(aes_ctx_pkcs11, PR_TRUE);
12225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (rv != SECSuccess) goto loser;
12235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
12245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /* Convert ciphertext length to network order. */
12265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    length_buf[0] = (ciphertext.len >> 8) & 0xff;
12275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    length_buf[1] = (ciphertext.len     ) & 0xff;
12285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /* Compute MAC. */
12302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#ifndef NO_PKCS11_BYPASS
12315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (ss->opt.bypassPKCS11) {
12325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	hmac_ctx = (HMACContext *)hmac_ctx_buf;
12335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	hashObj = HASH_GetRawHashObject(HASH_AlgSHA256);
12345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (HMAC_Init(hmac_ctx, hashObj, mac_key,
12355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		mac_key_length, PR_FALSE) != SECSuccess)
12365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    goto loser;
12375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	HMAC_Begin(hmac_ctx);
12395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	HMAC_Update(hmac_ctx, key_name, SESS_TICKET_KEY_NAME_LEN);
12405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	HMAC_Update(hmac_ctx, iv, sizeof(iv));
12415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	HMAC_Update(hmac_ctx, (unsigned char *)length_buf, 2);
12425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	HMAC_Update(hmac_ctx, ciphertext.data, ciphertext.len);
12435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	HMAC_Finish(hmac_ctx, computed_mac, &computed_mac_length,
12445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    sizeof(computed_mac));
12452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    } else
12462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif
12472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    {
12485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	SECItem macParam;
12495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	macParam.data = NULL;
12505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	macParam.len = 0;
12515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	hmac_ctx_pkcs11 = PK11_CreateContextBySymKey(macMech,
12525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    CKA_SIGN, mac_key_pkcs11, &macParam);
12535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (!hmac_ctx_pkcs11)
12545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    goto loser;
12555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	rv = PK11_DigestBegin(hmac_ctx_pkcs11);
12575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	rv = PK11_DigestOp(hmac_ctx_pkcs11, key_name,
12585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    SESS_TICKET_KEY_NAME_LEN);
12595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	rv = PK11_DigestOp(hmac_ctx_pkcs11, iv, sizeof(iv));
12605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	rv = PK11_DigestOp(hmac_ctx_pkcs11, (unsigned char *)length_buf, 2);
12615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	rv = PK11_DigestOp(hmac_ctx_pkcs11, ciphertext.data, ciphertext.len);
12625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	rv = PK11_DigestFinal(hmac_ctx_pkcs11, computed_mac,
12635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    &computed_mac_length, sizeof(computed_mac));
12645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	PK11_DestroyContext(hmac_ctx_pkcs11, PR_TRUE);
12655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (rv != SECSuccess) goto loser;
12665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
12675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /* Serialize the handshake message. */
12695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rv = ssl3_AppendHandshakeHeader(ss, new_session_ticket, message_length);
12705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (rv != SECSuccess) goto loser;
12715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rv = ssl3_AppendHandshakeNumber(ss, ticket.ticket_lifetime_hint,
12735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	sizeof(ticket.ticket_lifetime_hint));
12745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (rv != SECSuccess) goto loser;
12755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rv = ssl3_AppendHandshakeNumber(ss,
12775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	message_length - sizeof(ticket.ticket_lifetime_hint) - 2, 2);
12785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (rv != SECSuccess) goto loser;
12795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rv = ssl3_AppendHandshake(ss, key_name, SESS_TICKET_KEY_NAME_LEN);
12815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (rv != SECSuccess) goto loser;
12825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rv = ssl3_AppendHandshake(ss, iv, sizeof(iv));
12845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (rv != SECSuccess) goto loser;
12855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rv = ssl3_AppendHandshakeVariable(ss, ciphertext.data, ciphertext.len, 2);
12875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (rv != SECSuccess) goto loser;
12885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rv = ssl3_AppendHandshake(ss, computed_mac, computed_mac_length);
12905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (rv != SECSuccess) goto loser;
12915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)loser:
12935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (plaintext_item.data)
12945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	SECITEM_FreeItem(&plaintext_item, PR_FALSE);
12955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (ciphertext.data)
12965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	SECITEM_FreeItem(&ciphertext, PR_FALSE);
12975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return rv;
12995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
13005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* When a client receives a SessionTicket extension a NewSessionTicket
13025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * message is expected during the handshake.
13035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
13045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SECStatus
13055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ssl3_ClientHandleSessionTicketXtn(sslSocket *ss, PRUint16 ex_type,
13065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  SECItem *data)
13075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
13085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (data->len != 0)
13095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return SECFailure;
13105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /* Keep track of negotiated extensions. */
13125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ss->xtnData.negotiated[ss->xtnData.numNegotiated++] = ex_type;
13135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return SECSuccess;
13145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
13155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SECStatus
13175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ssl3_ServerHandleSessionTicketXtn(sslSocket *ss, PRUint16 ex_type,
13185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  SECItem *data)
13195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
13205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SECStatus rv;
13215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SECItem *decrypted_state = NULL;
13225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SessionTicket *parsed_session_ticket = NULL;
13235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sslSessionID *sid = NULL;
13245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SSL3Statistics *ssl3stats;
13255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /* Ignore the SessionTicket extension if processing is disabled. */
13275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!ss->opt.enableSessionTickets)
13285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return SECSuccess;
13295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /* Keep track of negotiated extensions. */
13315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ss->xtnData.negotiated[ss->xtnData.numNegotiated++] = ex_type;
13325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /* Parse the received ticket sent in by the client.  We are
13345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * lenient about some parse errors, falling back to a fullshake
13355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * instead of terminating the current connection.
13365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     */
13375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (data->len == 0) {
13385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ss->xtnData.emptySessionTicket = PR_TRUE;
13395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else {
13405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	int                    i;
13415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	SECItem                extension_data;
13425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	EncryptedSessionTicket enc_session_ticket;
13435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	unsigned char          computed_mac[TLS_EX_SESS_TICKET_MAC_LENGTH];
13445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	unsigned int           computed_mac_length;
13452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#ifndef NO_PKCS11_BYPASS
13465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	const SECHashObject   *hashObj;
13475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	const unsigned char   *aes_key;
13485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	const unsigned char   *mac_key;
13495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	PRUint32               aes_key_length;
13505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	PRUint32               mac_key_length;
13515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	PRUint64               hmac_ctx_buf[MAX_MAC_CONTEXT_LLONGS];
13525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	HMACContext           *hmac_ctx;
13535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	PRUint64               aes_ctx_buf[MAX_CIPHER_CONTEXT_LLONGS];
13545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	AESContext            *aes_ctx;
13552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif
13562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)	PK11SymKey            *aes_key_pkcs11;
13572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)	PK11SymKey            *mac_key_pkcs11;
13582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)	PK11Context           *hmac_ctx_pkcs11;
13592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)	CK_MECHANISM_TYPE      macMech = CKM_SHA256_HMAC;
13605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	PK11Context           *aes_ctx_pkcs11;
13615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	CK_MECHANISM_TYPE      cipherMech = CKM_AES_CBC;
13625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	unsigned char *        padding;
13635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	PRUint32               padding_length;
13645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	unsigned char         *buffer;
13655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	unsigned int           buffer_len;
13665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	PRInt32                temp;
13675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	SECItem                cert_item;
13685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        PRInt8                 nameType = TLS_STE_NO_SERVER_NAME;
13695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/* Turn off stateless session resumption if the client sends a
13715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	 * SessionTicket extension, even if the extension turns out to be
13725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	 * malformed (ss->sec.ci.sid is non-NULL when doing session
13735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	 * renegotiation.)
13745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	 */
13755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (ss->sec.ci.sid != NULL) {
13765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    if (ss->sec.uncache)
13775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		ss->sec.uncache(ss->sec.ci.sid);
13785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    ssl_FreeSID(ss->sec.ci.sid);
13795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    ss->sec.ci.sid = NULL;
13805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
13815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	extension_data.data = data->data; /* Keep a copy for future use. */
13835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	extension_data.len = data->len;
13845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (ssl3_ParseEncryptedSessionTicket(ss, data, &enc_session_ticket)
13865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    != SECSuccess)
13875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    return SECFailure;
13885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/* Get session ticket keys. */
13902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#ifndef NO_PKCS11_BYPASS
13915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (ss->opt.bypassPKCS11) {
13925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    rv = ssl3_GetSessionTicketKeys(&aes_key, &aes_key_length,
13935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		&mac_key, &mac_key_length);
13942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)	} else
13952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif
1396c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)	{
13975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    rv = ssl3_GetSessionTicketKeysPKCS11(ss, &aes_key_pkcs11,
13985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		&mac_key_pkcs11);
13995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
14005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (rv != SECSuccess) {
14015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    SSL_DBG(("%d: SSL[%d]: Unable to get/generate session ticket keys.",
14025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			SSL_GETPID(), ss->fd));
14035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    goto loser;
14045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
14055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/* If the ticket sent by the client was generated under a key different
14075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	 * from the one we have, bypass ticket processing.
14085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	 */
14095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (PORT_Memcmp(enc_session_ticket.key_name, key_name,
14105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		SESS_TICKET_KEY_NAME_LEN) != 0) {
14115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    SSL_DBG(("%d: SSL[%d]: Session ticket key_name sent mismatch.",
14125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			SSL_GETPID(), ss->fd));
14135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    goto no_ticket;
14145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
14155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/* Verify the MAC on the ticket.  MAC verification may also
14175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	 * fail if the MAC key has been recently refreshed.
14185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	 */
14192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#ifndef NO_PKCS11_BYPASS
14205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (ss->opt.bypassPKCS11) {
14215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    hmac_ctx = (HMACContext *)hmac_ctx_buf;
14225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    hashObj = HASH_GetRawHashObject(HASH_AlgSHA256);
14235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    if (HMAC_Init(hmac_ctx, hashObj, mac_key,
14245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    sizeof(session_ticket_mac_key), PR_FALSE) != SECSuccess)
14255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		goto no_ticket;
14265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    HMAC_Begin(hmac_ctx);
14275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    HMAC_Update(hmac_ctx, extension_data.data,
14285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		extension_data.len - TLS_EX_SESS_TICKET_MAC_LENGTH);
14295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    if (HMAC_Finish(hmac_ctx, computed_mac, &computed_mac_length,
14305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    sizeof(computed_mac)) != SECSuccess)
14315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		goto no_ticket;
14322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)	} else
14332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif
1434c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)	{
14355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    SECItem macParam;
14365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    macParam.data = NULL;
14375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    macParam.len = 0;
14385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    hmac_ctx_pkcs11 = PK11_CreateContextBySymKey(macMech,
14395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		CKA_SIGN, mac_key_pkcs11, &macParam);
14405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    if (!hmac_ctx_pkcs11) {
14415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		SSL_DBG(("%d: SSL[%d]: Unable to create HMAC context: %d.",
14425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			    SSL_GETPID(), ss->fd, PORT_GetError()));
14435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		goto no_ticket;
14445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    } else {
14455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		SSL_DBG(("%d: SSL[%d]: Successfully created HMAC context.",
14465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			    SSL_GETPID(), ss->fd));
14475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    }
14485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    rv = PK11_DigestBegin(hmac_ctx_pkcs11);
14495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    rv = PK11_DigestOp(hmac_ctx_pkcs11, extension_data.data,
14505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		extension_data.len - TLS_EX_SESS_TICKET_MAC_LENGTH);
14515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    if (rv != SECSuccess) {
14525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		PK11_DestroyContext(hmac_ctx_pkcs11, PR_TRUE);
14535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		goto no_ticket;
14545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    }
14555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    rv = PK11_DigestFinal(hmac_ctx_pkcs11, computed_mac,
14565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		&computed_mac_length, sizeof(computed_mac));
14575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    PK11_DestroyContext(hmac_ctx_pkcs11, PR_TRUE);
14585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    if (rv != SECSuccess)
14595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		goto no_ticket;
14605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
14615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (NSS_SecureMemcmp(computed_mac, enc_session_ticket.mac,
14625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		computed_mac_length) != 0) {
14635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    SSL_DBG(("%d: SSL[%d]: Session ticket MAC mismatch.",
14645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			SSL_GETPID(), ss->fd));
14655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    goto no_ticket;
14665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
14675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/* We ignore key_name for now.
14695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	 * This is ok as MAC verification succeeded.
14705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	 */
14715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/* Decrypt the ticket. */
14735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/* Plaintext is shorter than the ciphertext due to padding. */
14755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	decrypted_state = SECITEM_AllocItem(NULL, NULL,
14765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    enc_session_ticket.encrypted_state.len);
14775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#ifndef NO_PKCS11_BYPASS
14795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (ss->opt.bypassPKCS11) {
14805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    aes_ctx = (AESContext *)aes_ctx_buf;
14815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    rv = AES_InitContext(aes_ctx, aes_key,
14825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		sizeof(session_ticket_enc_key), enc_session_ticket.iv,
14835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		NSS_AES_CBC, 0,AES_BLOCK_SIZE);
14845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    if (rv != SECSuccess) {
14855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		SSL_DBG(("%d: SSL[%d]: Unable to create AES context.",
14865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			    SSL_GETPID(), ss->fd));
14875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		goto no_ticket;
14885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    }
14895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    rv = AES_Decrypt(aes_ctx, decrypted_state->data,
14915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		&decrypted_state->len, decrypted_state->len,
14925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		enc_session_ticket.encrypted_state.data,
14935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		enc_session_ticket.encrypted_state.len);
14945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    if (rv != SECSuccess)
14955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		goto no_ticket;
14962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)	} else
14972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif
1498c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)	{
14995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    SECItem ivItem;
15005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    ivItem.data = enc_session_ticket.iv;
15015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    ivItem.len = AES_BLOCK_SIZE;
15025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    aes_ctx_pkcs11 = PK11_CreateContextBySymKey(cipherMech,
15035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		CKA_DECRYPT, aes_key_pkcs11, &ivItem);
15045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    if (!aes_ctx_pkcs11) {
15055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		SSL_DBG(("%d: SSL[%d]: Unable to create AES context.",
15065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			    SSL_GETPID(), ss->fd));
15075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		goto no_ticket;
15085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    }
15095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    rv = PK11_CipherOp(aes_ctx_pkcs11, decrypted_state->data,
15115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		(int *)&decrypted_state->len, decrypted_state->len,
15125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		enc_session_ticket.encrypted_state.data,
15135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		enc_session_ticket.encrypted_state.len);
15145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    PK11_Finalize(aes_ctx_pkcs11);
15155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    PK11_DestroyContext(aes_ctx_pkcs11, PR_TRUE);
15165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    if (rv != SECSuccess)
15175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		goto no_ticket;
15185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
15195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/* Check padding. */
15215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	padding_length =
15225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    (PRUint32)decrypted_state->data[decrypted_state->len - 1];
15235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (padding_length == 0 || padding_length > AES_BLOCK_SIZE)
15245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    goto no_ticket;
15255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	padding = &decrypted_state->data[decrypted_state->len - padding_length];
15275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	for (i = 0; i < padding_length; i++, padding++) {
15285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    if (padding_length != (PRUint32)*padding)
15295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		goto no_ticket;
15305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
15315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/* Deserialize session state. */
15335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	buffer = decrypted_state->data;
15345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	buffer_len = decrypted_state->len;
15355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	parsed_session_ticket = PORT_ZAlloc(sizeof(SessionTicket));
15375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (parsed_session_ticket == NULL) {
15385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    rv = SECFailure;
15395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    goto loser;
15405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
15415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/* Read ticket_version (which is ignored for now.) */
15435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	temp = ssl3_ConsumeHandshakeNumber(ss, 2, &buffer, &buffer_len);
15445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (temp < 0) goto no_ticket;
15455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	parsed_session_ticket->ticket_version = (SSL3ProtocolVersion)temp;
15465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/* Read SSLVersion. */
15485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	temp = ssl3_ConsumeHandshakeNumber(ss, 2, &buffer, &buffer_len);
15495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (temp < 0) goto no_ticket;
15505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	parsed_session_ticket->ssl_version = (SSL3ProtocolVersion)temp;
15515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/* Read cipher_suite. */
15535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	temp =  ssl3_ConsumeHandshakeNumber(ss, 2, &buffer, &buffer_len);
15545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (temp < 0) goto no_ticket;
15555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	parsed_session_ticket->cipher_suite = (ssl3CipherSuite)temp;
15565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/* Read compression_method. */
15585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	temp = ssl3_ConsumeHandshakeNumber(ss, 1, &buffer, &buffer_len);
15595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (temp < 0) goto no_ticket;
15605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	parsed_session_ticket->compression_method = (SSLCompressionMethod)temp;
15615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/* Read cipher spec parameters. */
15635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	temp = ssl3_ConsumeHandshakeNumber(ss, 1, &buffer, &buffer_len);
15645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (temp < 0) goto no_ticket;
15655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	parsed_session_ticket->authAlgorithm = (SSLSignType)temp;
15665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	temp = ssl3_ConsumeHandshakeNumber(ss, 4, &buffer, &buffer_len);
15675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (temp < 0) goto no_ticket;
15685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	parsed_session_ticket->authKeyBits = (PRUint32)temp;
15695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	temp = ssl3_ConsumeHandshakeNumber(ss, 1, &buffer, &buffer_len);
15705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (temp < 0) goto no_ticket;
15715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	parsed_session_ticket->keaType = (SSLKEAType)temp;
15725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	temp = ssl3_ConsumeHandshakeNumber(ss, 4, &buffer, &buffer_len);
15735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (temp < 0) goto no_ticket;
15745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	parsed_session_ticket->keaKeyBits = (PRUint32)temp;
15755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/* Read wrapped master_secret. */
15775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	temp = ssl3_ConsumeHandshakeNumber(ss, 1, &buffer, &buffer_len);
15785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (temp < 0) goto no_ticket;
15795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	parsed_session_ticket->ms_is_wrapped = (PRBool)temp;
15805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	temp = ssl3_ConsumeHandshakeNumber(ss, 1, &buffer, &buffer_len);
15825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (temp < 0) goto no_ticket;
15835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	parsed_session_ticket->exchKeyType = (SSL3KEAType)temp;
15845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	temp = ssl3_ConsumeHandshakeNumber(ss, 4, &buffer, &buffer_len);
15865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (temp < 0) goto no_ticket;
15875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	parsed_session_ticket->msWrapMech = (CK_MECHANISM_TYPE)temp;
15885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	temp = ssl3_ConsumeHandshakeNumber(ss, 2, &buffer, &buffer_len);
15905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (temp < 0) goto no_ticket;
15915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	parsed_session_ticket->ms_length = (PRUint16)temp;
15925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (parsed_session_ticket->ms_length == 0 ||  /* sanity check MS. */
15935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    parsed_session_ticket->ms_length >
15945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    sizeof(parsed_session_ticket->master_secret))
15955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    goto no_ticket;
15965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/* Allow for the wrapped master secret to be longer. */
15985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (buffer_len < sizeof(SSL3_MASTER_SECRET_LENGTH))
15995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    goto no_ticket;
16005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	PORT_Memcpy(parsed_session_ticket->master_secret, buffer,
16015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    parsed_session_ticket->ms_length);
16025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	buffer += parsed_session_ticket->ms_length;
16035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	buffer_len -= parsed_session_ticket->ms_length;
16045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/* Read client_identity */
16065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	temp = ssl3_ConsumeHandshakeNumber(ss, 1, &buffer, &buffer_len);
16075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (temp < 0)
16085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    goto no_ticket;
16095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	parsed_session_ticket->client_identity.client_auth_type =
16105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    (ClientAuthenticationType)temp;
16115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	switch(parsed_session_ticket->client_identity.client_auth_type) {
16125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            case CLIENT_AUTH_ANONYMOUS:
16135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		break;
16145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            case CLIENT_AUTH_CERTIFICATE:
16155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		rv = ssl3_ConsumeHandshakeVariable(ss, &cert_item, 3,
16165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    &buffer, &buffer_len);
16175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		if (rv != SECSuccess) goto no_ticket;
16185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		rv = SECITEM_CopyItem(NULL, &parsed_session_ticket->peer_cert,
16195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    &cert_item);
16205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		if (rv != SECSuccess) goto no_ticket;
16215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		break;
16225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            default:
16235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		goto no_ticket;
16245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
16255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/* Read timestamp. */
16265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	temp = ssl3_ConsumeHandshakeNumber(ss, 4, &buffer, &buffer_len);
16275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (temp < 0)
16285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    goto no_ticket;
16295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	parsed_session_ticket->timestamp = (PRUint32)temp;
16305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        /* Read server name */
16325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        nameType =
16335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                ssl3_ConsumeHandshakeNumber(ss, 1, &buffer, &buffer_len);
16345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if (nameType != TLS_STE_NO_SERVER_NAME) {
16355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            SECItem name_item;
16365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            rv = ssl3_ConsumeHandshakeVariable(ss, &name_item, 2, &buffer,
16375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                               &buffer_len);
16385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            if (rv != SECSuccess) goto no_ticket;
16395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            rv = SECITEM_CopyItem(NULL, &parsed_session_ticket->srvName,
16405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  &name_item);
16415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            if (rv != SECSuccess) goto no_ticket;
16425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            parsed_session_ticket->srvName.type = nameType;
16435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
16445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/* Done parsing.  Check that all bytes have been consumed. */
16465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (buffer_len != padding_length)
16475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    goto no_ticket;
16485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/* Use the ticket if it has not expired, otherwise free the allocated
16505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	 * memory since the ticket is of no use.
16515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	 */
16525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (parsed_session_ticket->timestamp != 0 &&
16535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    parsed_session_ticket->timestamp +
16545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    TLS_EX_SESS_TICKET_LIFETIME_HINT > ssl_Time()) {
16555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    sid = ssl3_NewSessionID(ss, PR_TRUE);
16575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    if (sid == NULL) {
16585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		rv = SECFailure;
16595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		goto loser;
16605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    }
16615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    /* Copy over parameters. */
16635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    sid->version = parsed_session_ticket->ssl_version;
16645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    sid->u.ssl3.cipherSuite = parsed_session_ticket->cipher_suite;
16655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    sid->u.ssl3.compression = parsed_session_ticket->compression_method;
16665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    sid->authAlgorithm = parsed_session_ticket->authAlgorithm;
16675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    sid->authKeyBits = parsed_session_ticket->authKeyBits;
16685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    sid->keaType = parsed_session_ticket->keaType;
16695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    sid->keaKeyBits = parsed_session_ticket->keaKeyBits;
16705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    /* Copy master secret. */
16722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#ifndef NO_PKCS11_BYPASS
16735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    if (ss->opt.bypassPKCS11 &&
16745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    parsed_session_ticket->ms_is_wrapped)
16755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		goto no_ticket;
16762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif
16775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    if (parsed_session_ticket->ms_length >
16785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    sizeof(sid->u.ssl3.keys.wrapped_master_secret))
16795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		goto no_ticket;
16805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    PORT_Memcpy(sid->u.ssl3.keys.wrapped_master_secret,
16815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		parsed_session_ticket->master_secret,
16825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		parsed_session_ticket->ms_length);
16835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    sid->u.ssl3.keys.wrapped_master_secret_len =
16845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		parsed_session_ticket->ms_length;
16855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    sid->u.ssl3.exchKeyType = parsed_session_ticket->exchKeyType;
16865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    sid->u.ssl3.masterWrapMech = parsed_session_ticket->msWrapMech;
16875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    sid->u.ssl3.keys.msIsWrapped =
16885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		parsed_session_ticket->ms_is_wrapped;
16895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    sid->u.ssl3.masterValid    = PR_TRUE;
16905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    sid->u.ssl3.keys.resumable = PR_TRUE;
16915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    /* Copy over client cert from session ticket if there is one. */
16935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    if (parsed_session_ticket->peer_cert.data != NULL) {
16945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		if (sid->peerCert != NULL)
16955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    CERT_DestroyCertificate(sid->peerCert);
16965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		sid->peerCert = CERT_NewTempCertificate(ss->dbHandle,
16975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    &parsed_session_ticket->peer_cert, NULL, PR_FALSE, PR_TRUE);
16985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		if (sid->peerCert == NULL) {
16995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    rv = SECFailure;
17005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    goto loser;
17015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		}
17025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    }
17035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    if (parsed_session_ticket->srvName.data != NULL) {
17045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                sid->u.ssl3.srvName = parsed_session_ticket->srvName;
17055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            }
17065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    ss->statelessResume = PR_TRUE;
17075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    ss->sec.ci.sid = sid;
17085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
17095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
17105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (0) {
17125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)no_ticket:
17135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	SSL_DBG(("%d: SSL[%d]: Session ticket parsing failed.",
17145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			SSL_GETPID(), ss->fd));
17155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ssl3stats = SSL_GetStatistics();
17165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	SSL_AtomicIncrementLong(& ssl3stats->hch_sid_ticket_parse_failures );
17175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
17185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rv = SECSuccess;
17195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)loser:
17215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/* ss->sec.ci.sid == sid if it did NOT come here via goto statement
17225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	 * in that case do not free sid
17235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	 */
17245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (sid && (ss->sec.ci.sid != sid)) {
17255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    ssl_FreeSID(sid);
17265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    sid = NULL;
17275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
17285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (decrypted_state != NULL) {
17295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	SECITEM_FreeItem(decrypted_state, PR_TRUE);
17305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	decrypted_state = NULL;
17315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
17325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (parsed_session_ticket != NULL) {
17345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (parsed_session_ticket->peer_cert.data) {
17355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    SECITEM_FreeItem(&parsed_session_ticket->peer_cert, PR_FALSE);
17365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
17375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	PORT_ZFree(parsed_session_ticket, sizeof(SessionTicket));
17385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
17395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return rv;
17415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
17425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
17445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Read bytes.  Using this function means the SECItem structure
17455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * cannot be freed.  The caller is expected to call this function
17465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * on a shallow copy of the structure.
17475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
17485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static SECStatus
17495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ssl3_ConsumeFromItem(SECItem *item, unsigned char **buf, PRUint32 bytes)
17505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
17515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (bytes > item->len)
17525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return SECFailure;
17535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    *buf = item->data;
17555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    item->data += bytes;
17565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    item->len -= bytes;
17575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return SECSuccess;
17585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
17595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static SECStatus
17615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ssl3_ParseEncryptedSessionTicket(sslSocket *ss, SECItem *data,
17625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 EncryptedSessionTicket *enc_session_ticket)
17635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
17645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (ssl3_ConsumeFromItem(data, &enc_session_ticket->key_name,
17655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    SESS_TICKET_KEY_NAME_LEN) != SECSuccess)
17665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return SECFailure;
17675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (ssl3_ConsumeFromItem(data, &enc_session_ticket->iv,
17685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    AES_BLOCK_SIZE) != SECSuccess)
17695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return SECFailure;
17705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (ssl3_ConsumeHandshakeVariable(ss, &enc_session_ticket->encrypted_state,
17715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    2, &data->data, &data->len) != SECSuccess)
17725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return SECFailure;
17735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (ssl3_ConsumeFromItem(data, &enc_session_ticket->mac,
17745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    TLS_EX_SESS_TICKET_MAC_LENGTH) != SECSuccess)
17755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return SECFailure;
17765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (data->len != 0)  /* Make sure that we have consumed all bytes. */
17775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return SECFailure;
17785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return SECSuccess;
17805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
17815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* go through hello extensions in buffer "b".
17835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * For each one, find the extension handler in the table, and
17845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * if present, invoke that handler.
17855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Servers ignore any extensions with unknown extension types.
17865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Clients reject any extensions with unadvertised extension types.
17875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
17885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SECStatus
17895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ssl3_HandleHelloExtensions(sslSocket *ss, SSL3Opaque **b, PRUint32 *length)
17905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
17915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const ssl3HelloExtensionHandler * handlers;
17925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (ss->sec.isServer) {
17945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        handlers = clientHelloHandlers;
17955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else if (ss->version > SSL_LIBRARY_VERSION_3_0) {
17965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        handlers = serverHelloHandlersTLS;
17975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else {
17985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        handlers = serverHelloHandlersSSL3;
17995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
18005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    while (*length) {
18025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	const ssl3HelloExtensionHandler * handler;
18035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	SECStatus rv;
18045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	PRInt32   extension_type;
18055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	SECItem   extension_data;
18065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/* Get the extension's type field */
18085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	extension_type = ssl3_ConsumeHandshakeNumber(ss, 2, b, length);
18095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (extension_type < 0)  /* failure to decode extension_type */
18105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    return SECFailure;   /* alert already sent */
18115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/* get the data for this extension, so we can pass it or skip it. */
18135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	rv = ssl3_ConsumeHandshakeVariable(ss, &extension_data, 2, b, length);
18145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (rv != SECSuccess)
18155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    return rv;
18165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/* Check whether the server sent an extension which was not advertised
18185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	 * in the ClientHello.
18195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	 */
18205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (!ss->sec.isServer &&
18215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    !ssl3_ClientExtensionAdvertised(ss, extension_type))
18225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    return SECFailure;  /* TODO: send unsupported_extension alert */
18235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/* Check whether an extension has been sent multiple times. */
18255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (ssl3_ExtensionNegotiated(ss, extension_type))
18265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    return SECFailure;
18275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/* find extension_type in table of Hello Extension Handlers */
18295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	for (handler = handlers; handler->ex_type >= 0; handler++) {
18305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    /* if found, call this handler */
18315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    if (handler->ex_type == extension_type) {
18325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		rv = (*handler->ex_handler)(ss, (PRUint16)extension_type,
18335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	                                         	&extension_data);
18345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		/* Ignore this result */
18355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		/* Treat all bad extensions as unrecognized types. */
18365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	        break;
18375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    }
18385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
18395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
18405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return SECSuccess;
18415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
18425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* Add a callback function to the table of senders of server hello extensions.
18445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
18455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SECStatus
18465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ssl3_RegisterServerHelloExtensionSender(sslSocket *ss, PRUint16 ex_type,
18475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				        ssl3HelloExtensionSenderFunc cb)
18485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
18495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int i;
18505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ssl3HelloExtensionSender *sender = &ss->xtnData.serverSenders[0];
18515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for (i = 0; i < SSL_MAX_EXTENSIONS; ++i, ++sender) {
18535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if (!sender->ex_sender) {
18545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    sender->ex_type   = ex_type;
18555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    sender->ex_sender = cb;
18565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    return SECSuccess;
18575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
18585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/* detect duplicate senders */
18595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	PORT_Assert(sender->ex_type != ex_type);
18605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (sender->ex_type == ex_type) {
18615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    /* duplicate */
18625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    break;
18635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
18645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
18655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PORT_Assert(i < SSL_MAX_EXTENSIONS); /* table needs to grow */
18665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
18675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return SECFailure;
18685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
18695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* call each of the extension senders and return the accumulated length */
18715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PRInt32
18725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ssl3_CallHelloExtensionSenders(sslSocket *ss, PRBool append, PRUint32 maxBytes,
18735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               const ssl3HelloExtensionSender *sender)
18745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
18755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PRInt32 total_exten_len = 0;
18765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int i;
18775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!sender) {
18795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    	sender = ss->version > SSL_LIBRARY_VERSION_3_0 ?
18805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 &clientHelloSendersTLS[0] : &clientHelloSendersSSL3[0];
18815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
18825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for (i = 0; i < SSL_MAX_EXTENSIONS; ++i, ++sender) {
18845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (sender->ex_sender) {
18855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    PRInt32 extLen = (*sender->ex_sender)(ss, append, maxBytes);
18865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    if (extLen < 0)
18875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    	return -1;
18885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    maxBytes        -= extLen;
18895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    total_exten_len += extLen;
18905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
18915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
18925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return total_exten_len;
18935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
18945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* Extension format:
18975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Extension number:   2 bytes
18985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Extension length:   2 bytes
18995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Verify Data Length: 1 byte
19005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Verify Data (TLS): 12 bytes (client) or 24 bytes (server)
19015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Verify Data (SSL): 36 bytes (client) or 72 bytes (server)
19025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
19035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static PRInt32
19045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ssl3_SendRenegotiationInfoXtn(
19055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			sslSocket * ss,
19065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			PRBool      append,
19075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			PRUint32    maxBytes)
19085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
19095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PRInt32 len, needed;
19105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /* In draft-ietf-tls-renegotiation-03, it is NOT RECOMMENDED to send
19125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * both the SCSV and the empty RI, so when we send SCSV in
19135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * the initial handshake, we don't also send RI.
19145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     */
19155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!ss || ss->ssl3.hs.sendingSCSV)
19165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    	return 0;
19175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    len = !ss->firstHsDone ? 0 :
19185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	   (ss->sec.isServer ? ss->ssl3.hs.finishedBytes * 2
19195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			     : ss->ssl3.hs.finishedBytes);
19205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    needed = 5 + len;
19215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (append && maxBytes >= needed) {
19225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	SECStatus rv;
19235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/* extension_type */
19245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	rv = ssl3_AppendHandshakeNumber(ss, ssl_renegotiation_info_xtn, 2);
19255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (rv != SECSuccess) return -1;
19265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/* length of extension_data */
19275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	rv = ssl3_AppendHandshakeNumber(ss, len + 1, 2);
19285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (rv != SECSuccess) return -1;
19295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/* verify_Data from previous Finished message(s) */
19305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	rv = ssl3_AppendHandshakeVariable(ss,
19315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		  ss->ssl3.hs.finishedMsgs.data, len, 1);
19325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (rv != SECSuccess) return -1;
19335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (!ss->sec.isServer) {
19345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    TLSExtensionData *xtnData = &ss->xtnData;
19355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    xtnData->advertised[xtnData->numAdvertised++] =
19365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	                                           ssl_renegotiation_info_xtn;
19375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
19385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
19395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return needed;
19405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
19415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1942c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)static SECStatus
1943c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)ssl3_ServerHandleStatusRequestXtn(sslSocket *ss, PRUint16 ex_type,
1944c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)				  SECItem *data)
1945c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles){
1946c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    SECStatus rv = SECSuccess;
1947c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1948c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    /* remember that we got this extension. */
1949c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    ss->xtnData.negotiated[ss->xtnData.numNegotiated++] = ex_type;
1950c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    PORT_Assert(ss->sec.isServer);
1951c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    /* prepare to send back the appropriate response */
1952c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    rv = ssl3_RegisterServerHelloExtensionSender(ss, ex_type,
1953c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)					    ssl3_ServerSendStatusRequestXtn);
1954c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return rv;
1955c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
1956c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
19575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* This function runs in both the client and server.  */
19585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static SECStatus
19595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ssl3_HandleRenegotiationInfoXtn(sslSocket *ss, PRUint16 ex_type, SECItem *data)
19605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
19615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SECStatus rv = SECSuccess;
19625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PRUint32 len = 0;
19635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (ss->firstHsDone) {
19655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	len = ss->sec.isServer ? ss->ssl3.hs.finishedBytes
19665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	                       : ss->ssl3.hs.finishedBytes * 2;
19675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
19685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (data->len != 1 + len  ||
19695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	data->data[0] != len  || (len &&
19705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	NSS_SecureMemcmp(ss->ssl3.hs.finishedMsgs.data,
19715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	                 data->data + 1, len))) {
19725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/* Can we do this here? Or, must we arrange for the caller to do it? */
19735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	(void)SSL3_SendAlert(ss, alert_fatal, handshake_failure);
19745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	PORT_SetError(SSL_ERROR_BAD_HANDSHAKE_HASH_VALUE);
19755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return SECFailure;
19765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
19775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /* remember that we got this extension and it was correct. */
19785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ss->peerRequestedProtection = 1;
19795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ss->xtnData.negotiated[ss->xtnData.numNegotiated++] = ex_type;
19805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (ss->sec.isServer) {
19815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/* prepare to send back the appropriate response */
19825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	rv = ssl3_RegisterServerHelloExtensionSender(ss, ex_type,
19835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)					     ssl3_SendRenegotiationInfoXtn);
19845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
19855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return rv;
19865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
19875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static PRInt32
19895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ssl3_SendUseSRTPXtn(sslSocket *ss, PRBool append, PRUint32 maxBytes)
19905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
19915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PRUint32 ext_data_len;
19925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PRInt16 i;
19935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SECStatus rv;
19945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!ss)
19965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return 0;
19975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!ss->sec.isServer) {
19995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/* Client side */
20005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (!IS_DTLS(ss) || !ss->ssl3.dtlsSRTPCipherCount)
20025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    return 0;  /* Not relevant */
20035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ext_data_len = 2 + 2 * ss->ssl3.dtlsSRTPCipherCount + 1;
20055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (append && maxBytes >= 4 + ext_data_len) {
20075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    /* Extension type */
20085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    rv = ssl3_AppendHandshakeNumber(ss, ssl_use_srtp_xtn, 2);
20095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    if (rv != SECSuccess) return -1;
20105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    /* Length of extension data */
20115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    rv = ssl3_AppendHandshakeNumber(ss, ext_data_len, 2);
20125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    if (rv != SECSuccess) return -1;
20135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    /* Length of the SRTP cipher list */
20145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    rv = ssl3_AppendHandshakeNumber(ss,
20155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)					    2 * ss->ssl3.dtlsSRTPCipherCount,
20165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)					    2);
20175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    if (rv != SECSuccess) return -1;
20185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    /* The SRTP ciphers */
20195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    for (i = 0; i < ss->ssl3.dtlsSRTPCipherCount; i++) {
20205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		rv = ssl3_AppendHandshakeNumber(ss,
20215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)						ss->ssl3.dtlsSRTPCiphers[i],
20225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)						2);
20235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    }
20245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    /* Empty MKI value */
20255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    ssl3_AppendHandshakeVariable(ss, NULL, 0, 1);
20265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    ss->xtnData.advertised[ss->xtnData.numAdvertised++] =
20285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		ssl_use_srtp_xtn;
20295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
20305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return 4 + ext_data_len;
20325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
20335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /* Server side */
20355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (append && maxBytes >= 9) {
20365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/* Extension type */
20375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	rv = ssl3_AppendHandshakeNumber(ss, ssl_use_srtp_xtn, 2);
20385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (rv != SECSuccess) return -1;
20395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/* Length of extension data */
20405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	rv = ssl3_AppendHandshakeNumber(ss, 5, 2);
20415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (rv != SECSuccess) return -1;
20425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/* Length of the SRTP cipher list */
20435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	rv = ssl3_AppendHandshakeNumber(ss, 2, 2);
20445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (rv != SECSuccess) return -1;
20455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/* The selected cipher */
20465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	rv = ssl3_AppendHandshakeNumber(ss, ss->ssl3.dtlsSRTPCipherSuite, 2);
20475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (rv != SECSuccess) return -1;
20485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/* Empty MKI value */
20495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ssl3_AppendHandshakeVariable(ss, NULL, 0, 1);
20505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
20515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return 9;
20535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
20545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static SECStatus
20565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ssl3_HandleUseSRTPXtn(sslSocket * ss, PRUint16 ex_type, SECItem *data)
20575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
20585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SECStatus rv;
20595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SECItem ciphers = {siBuffer, NULL, 0};
20602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    PRUint16 i;
20612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    unsigned int j;
20625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PRUint16 cipher = 0;
20635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PRBool found = PR_FALSE;
20645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SECItem litem;
20655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!ss->sec.isServer) {
20675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/* Client side */
20685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (!data->data || !data->len) {
20695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            /* malformed */
20705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            return SECFailure;
20715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
20725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/* Get the cipher list */
20745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	rv = ssl3_ConsumeHandshakeVariable(ss, &ciphers, 2,
20755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)					   &data->data, &data->len);
20765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (rv != SECSuccess) {
20775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    return SECFailure;
20785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
20795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/* Now check that the number of ciphers listed is 1 (len = 2) */
20805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (ciphers.len != 2) {
20815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    return SECFailure;
20825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
20835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/* Get the selected cipher */
20855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	cipher = (ciphers.data[0] << 8) | ciphers.data[1];
20865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/* Now check that this is one of the ciphers we offered */
20885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	for (i = 0; i < ss->ssl3.dtlsSRTPCipherCount; i++) {
20895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    if (cipher == ss->ssl3.dtlsSRTPCiphers[i]) {
20905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		found = PR_TRUE;
20915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		break;
20925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    }
20935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
20945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (!found) {
20965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    return SECFailure;
20975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
20985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/* Get the srtp_mki value */
21005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        rv = ssl3_ConsumeHandshakeVariable(ss, &litem, 1,
21015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)					   &data->data, &data->len);
21025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if (rv != SECSuccess) {
21035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            return SECFailure;
21045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
21055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/* We didn't offer an MKI, so this must be 0 length */
21075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/* XXX RFC 5764 Section 4.1.3 says:
21085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	 *   If the client detects a nonzero-length MKI in the server's
21095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	 *   response that is different than the one the client offered,
21105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	 *   then the client MUST abort the handshake and SHOULD send an
21115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	 *   invalid_parameter alert.
21125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	 *
21135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	 * Due to a limitation of the ssl3_HandleHelloExtensions function,
21145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	 * returning SECFailure here won't abort the handshake.  It will
21155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	 * merely cause the use_srtp extension to be not negotiated.  We
21165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	 * should fix this.  See NSS bug 753136.
21175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	 */
21185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (litem.len != 0) {
21195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    return SECFailure;
21205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
21215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (data->len != 0) {
21235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            /* malformed */
21245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            return SECFailure;
21255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
21265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/* OK, this looks fine. */
21285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ss->xtnData.negotiated[ss->xtnData.numNegotiated++] = ssl_use_srtp_xtn;
21295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ss->ssl3.dtlsSRTPCipherSuite = cipher;
21305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return SECSuccess;
21315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
21325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /* Server side */
21345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!IS_DTLS(ss) || !ss->ssl3.dtlsSRTPCipherCount) {
21355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/* Ignore the extension if we aren't doing DTLS or no DTLS-SRTP
21365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	 * preferences have been set. */
21375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return SECSuccess;
21385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
21395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!data->data || data->len < 5) {
21415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/* malformed */
21425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return SECFailure;
21435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
21445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /* Get the cipher list */
21465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rv = ssl3_ConsumeHandshakeVariable(ss, &ciphers, 2,
21475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				       &data->data, &data->len);
21485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (rv != SECSuccess) {
21495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return SECFailure;
21505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
21515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /* Check that the list is even length */
21525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (ciphers.len % 2) {
21535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return SECFailure;
21545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
21555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /* Walk through the offered list and pick the most preferred of our
21575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * ciphers, if any */
21585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for (i = 0; !found && i < ss->ssl3.dtlsSRTPCipherCount; i++) {
21595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	for (j = 0; j + 1 < ciphers.len; j += 2) {
21605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    cipher = (ciphers.data[j] << 8) | ciphers.data[j + 1];
21615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    if (cipher == ss->ssl3.dtlsSRTPCiphers[i]) {
21625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		found = PR_TRUE;
21635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		break;
21645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    }
21655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
21665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
21675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /* Get the srtp_mki value */
21695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rv = ssl3_ConsumeHandshakeVariable(ss, &litem, 1, &data->data, &data->len);
21705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (rv != SECSuccess) {
21715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return SECFailure;
21725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
21735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (data->len != 0) {
21755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return SECFailure; /* Malformed */
21765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
21775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /* Now figure out what to do */
21795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!found) {
21805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/* No matching ciphers */
21815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return SECSuccess;
21825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
21835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /* OK, we have a valid cipher and we've selected it */
21855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ss->ssl3.dtlsSRTPCipherSuite = cipher;
21865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ss->xtnData.negotiated[ss->xtnData.numNegotiated++] = ssl_use_srtp_xtn;
21875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return ssl3_RegisterServerHelloExtensionSender(ss, ssl_use_srtp_xtn,
21895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)						   ssl3_SendUseSRTPXtn);
21905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2191868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
2192868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)/* ssl3_ServerHandleSigAlgsXtn handles the signature_algorithms extension
2193868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) * from a client.
2194868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) * See https://tools.ietf.org/html/rfc5246#section-7.4.1.4.1 */
2195868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)static SECStatus
2196868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)ssl3_ServerHandleSigAlgsXtn(sslSocket * ss, PRUint16 ex_type, SECItem *data)
2197868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles){
2198868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    SECStatus rv;
2199868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    SECItem algorithms;
2200868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    const unsigned char *b;
2201868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    unsigned int numAlgorithms, i;
2202868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
2203868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    /* Ignore this extension if we aren't doing TLS 1.2 or greater. */
2204868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    if (ss->version < SSL_LIBRARY_VERSION_TLS_1_2) {
2205868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)	return SECSuccess;
2206868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    }
2207868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
2208868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    /* Keep track of negotiated extensions. */
2209868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    ss->xtnData.negotiated[ss->xtnData.numNegotiated++] = ex_type;
2210868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
2211868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    rv = ssl3_ConsumeHandshakeVariable(ss, &algorithms, 2, &data->data,
2212868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)				       &data->len);
2213868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    if (rv != SECSuccess) {
2214868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)	return SECFailure;
2215868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    }
2216868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    /* Trailing data, empty value, or odd-length value is invalid. */
2217868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    if (data->len != 0 || algorithms.len == 0 || (algorithms.len & 1) != 0) {
2218868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)	PORT_SetError(SSL_ERROR_RX_MALFORMED_CLIENT_HELLO);
2219868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)	return SECFailure;
2220868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    }
2221868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
2222868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    numAlgorithms = algorithms.len/2;
2223868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
2224868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    /* We don't care to process excessive numbers of algorithms. */
2225868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    if (numAlgorithms > 512) {
2226868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)	numAlgorithms = 512;
2227868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    }
2228868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
2229868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    ss->ssl3.hs.clientSigAndHash =
2230868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)	    PORT_NewArray(SSL3SignatureAndHashAlgorithm, numAlgorithms);
2231868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    if (!ss->ssl3.hs.clientSigAndHash) {
2232868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)	return SECFailure;
2233868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    }
2234868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    ss->ssl3.hs.numClientSigAndHash = 0;
2235868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
2236868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    b = algorithms.data;
2237868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    for (i = 0; i < numAlgorithms; i++) {
2238868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)	unsigned char tls_hash = *(b++);
2239868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)	unsigned char tls_sig = *(b++);
2240868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)	SECOidTag hash = ssl3_TLSHashAlgorithmToOID(tls_hash);
2241868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
2242868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)	if (hash == SEC_OID_UNKNOWN) {
2243868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)	    /* We ignore formats that we don't understand. */
2244868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)	    continue;
2245868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)	}
2246868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)	/* tls_sig support will be checked later in
2247868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)	 * ssl3_PickSignatureHashAlgorithm. */
2248868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)	ss->ssl3.hs.clientSigAndHash[i].hashAlg = hash;
2249868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)	ss->ssl3.hs.clientSigAndHash[i].sigAlg = tls_sig;
2250868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)	ss->ssl3.hs.numClientSigAndHash++;
2251868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    }
2252868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
2253868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    if (!ss->ssl3.hs.numClientSigAndHash) {
2254868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)	/* We didn't understand any of the client's requested signature
2255868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)	 * formats. We'll use the defaults. */
2256868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)	PORT_Free(ss->ssl3.hs.clientSigAndHash);
2257868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)	ss->ssl3.hs.clientSigAndHash = NULL;
2258868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    }
2259868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
2260868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    return SECSuccess;
2261868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
2262868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
2263868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)/* ssl3_ClientSendSigAlgsXtn sends the signature_algorithm extension for TLS
2264868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) * 1.2 ClientHellos. */
2265868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)static PRInt32
2266868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)ssl3_ClientSendSigAlgsXtn(sslSocket * ss, PRBool append, PRUint32 maxBytes)
2267868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles){
2268a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    static const unsigned char signatureAlgorithms[] = {
2269a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)	/* This block is the contents of our signature_algorithms extension, in
2270a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)	 * wire format. See
2271a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)	 * https://tools.ietf.org/html/rfc5246#section-7.4.1.4.1 */
2272a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)	tls_hash_sha256, tls_sig_rsa,
2273a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)	tls_hash_sha384, tls_sig_rsa,
2274a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)	tls_hash_sha1,   tls_sig_rsa,
2275a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)#ifdef NSS_ENABLE_ECC
2276a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)	tls_hash_sha256, tls_sig_ecdsa,
2277a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)	tls_hash_sha384, tls_sig_ecdsa,
2278a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)	tls_hash_sha1,   tls_sig_ecdsa,
2279a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)#endif
2280a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)	tls_hash_sha256, tls_sig_dsa,
2281a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)	tls_hash_sha1,   tls_sig_dsa,
2282a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    };
2283868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    PRInt32 extension_length;
2284868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
2285868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    if (ss->version < SSL_LIBRARY_VERSION_TLS_1_2) {
2286868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)	return 0;
2287868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    }
2288868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
2289868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    extension_length =
2290868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)	2 /* extension type */ +
2291868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)	2 /* extension length */ +
2292868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)	2 /* supported_signature_algorithms length */ +
2293a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)	sizeof(signatureAlgorithms);
2294868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
2295868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    if (append && maxBytes >= extension_length) {
2296868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)	SECStatus rv;
2297868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)	rv = ssl3_AppendHandshakeNumber(ss, ssl_signature_algorithms_xtn, 2);
2298868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)	if (rv != SECSuccess)
2299868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)	    goto loser;
2300868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)	rv = ssl3_AppendHandshakeNumber(ss, extension_length - 4, 2);
2301868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)	if (rv != SECSuccess)
2302868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)	    goto loser;
2303a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)	rv = ssl3_AppendHandshakeVariable(ss, signatureAlgorithms,
2304a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)					  sizeof(signatureAlgorithms), 2);
2305868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)	if (rv != SECSuccess)
2306868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)	    goto loser;
2307868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)	ss->xtnData.advertised[ss->xtnData.numAdvertised++] =
2308868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)		ssl_signature_algorithms_xtn;
2309868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    } else if (maxBytes < extension_length) {
2310868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)	PORT_Assert(0);
2311868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)	return 0;
2312868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    }
2313868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
2314868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    return extension_length;
2315868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
2316868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)loser:
2317868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    return -1;
2318868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
2319f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
2320f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)unsigned int
2321f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)ssl3_CalculatePaddingExtensionLength(unsigned int clientHelloLength)
2322f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles){
2323f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    unsigned int recordLength = 1 /* handshake message type */ +
2324f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)				3 /* handshake message length */ +
2325f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)				clientHelloLength;
2326f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    unsigned int extensionLength;
2327f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
2328f5859ba46034e02ada5ef522d9d9c09fbbddccd8Ben Murdoch    if (recordLength < 256 || recordLength >= 512) {
2329f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)	return 0;
2330f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    }
2331f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
2332f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)     extensionLength = 512 - recordLength;
2333f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)     /* Extensions take at least four bytes to encode. */
2334f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)     if (extensionLength < 4) {
2335f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)	 extensionLength = 4;
2336f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)     }
2337f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
2338f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)     return extensionLength;
2339f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
2340f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
2341f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)/* ssl3_AppendPaddingExtension possibly adds an extension which ensures that a
2342f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) * ClientHello record is either < 256 bytes or is >= 512 bytes. This ensures
2343f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) * that we don't trigger bugs in F5 products. */
2344f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)PRInt32
2345f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)ssl3_AppendPaddingExtension(sslSocket *ss, unsigned int extensionLen,
2346f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)			    PRUint32 maxBytes)
2347f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles){
2348f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    unsigned int paddingLen = extensionLen - 4;
2349f5859ba46034e02ada5ef522d9d9c09fbbddccd8Ben Murdoch    unsigned char padding[256];
2350f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
2351f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    if (extensionLen == 0) {
2352f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)	return 0;
2353f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    }
2354f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
2355f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    if (extensionLen < 4 ||
2356f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)	extensionLen > maxBytes ||
2357f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)	paddingLen > sizeof(padding)) {
2358f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)	PORT_Assert(0);
2359f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)	return -1;
2360f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    }
2361f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
2362f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    if (SECSuccess != ssl3_AppendHandshakeNumber(ss, ssl_padding_xtn, 2))
2363f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)	return -1;
2364f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    if (SECSuccess != ssl3_AppendHandshakeNumber(ss, paddingLen, 2))
2365f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)	return -1;
2366a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    memset(padding, 0, paddingLen);
2367f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    if (SECSuccess != ssl3_AppendHandshake(ss, padding, paddingLen))
2368f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)	return -1;
2369f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
2370f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    return extensionLen;
2371f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
2372f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
2373f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)/* ssl3_ClientSendSignedCertTimestampXtn sends the signed_certificate_timestamp
2374f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) * extension for TLS ClientHellos. */
2375f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)static PRInt32
2376f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)ssl3_ClientSendSignedCertTimestampXtn(sslSocket *ss, PRBool append,
2377f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)				      PRUint32 maxBytes)
2378f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles){
2379f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    PRInt32 extension_length = 2 /* extension_type */ +
2380f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)	    2 /* length(extension_data) */;
2381f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
2382f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    /* Only send the extension if processing is enabled. */
2383f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    if (!ss->opt.enableSignedCertTimestamps)
2384f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)	return 0;
2385f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
2386f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    if (append && maxBytes >= extension_length) {
2387f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)	SECStatus rv;
2388f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)	/* extension_type */
2389f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)	rv = ssl3_AppendHandshakeNumber(ss,
2390f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)					ssl_signed_certificate_timestamp_xtn,
2391f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)					2);
2392f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)	if (rv != SECSuccess)
2393f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)	    goto loser;
2394f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)	/* zero length */
2395f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)	rv = ssl3_AppendHandshakeNumber(ss, 0, 2);
2396f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)	if (rv != SECSuccess)
2397f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)	    goto loser;
2398f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)	ss->xtnData.advertised[ss->xtnData.numAdvertised++] =
2399f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)		ssl_signed_certificate_timestamp_xtn;
2400f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    } else if (maxBytes < extension_length) {
2401f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)	PORT_Assert(0);
2402f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)	return 0;
2403f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    }
2404f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
2405f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    return extension_length;
2406f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)loser:
2407f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    return -1;
2408f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
2409f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
2410f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)static SECStatus
2411f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)ssl3_ClientHandleSignedCertTimestampXtn(sslSocket *ss, PRUint16 ex_type,
2412f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)					SECItem *data)
2413f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles){
2414f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    /* We do not yet know whether we'll be resuming a session or creating
2415f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)     * a new one, so we keep a pointer to the data in the TLSExtensionData
2416f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)     * structure. This pointer is only valid in the scope of
2417f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)     * ssl3_HandleServerHello, and, if not resuming a session, the data is
2418f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)     * copied once a new session structure has been set up.
2419f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)     * All parsing is currently left to the application and we accept
2420f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)     * everything, including empty data.
2421f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)     */
2422f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    SECItem *scts = &ss->xtnData.signedCertTimestamps;
2423f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    PORT_Assert(!scts->data && !scts->len);
2424f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
2425f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    if (!data->len) {
2426f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)	/* Empty extension data: RFC 6962 mandates non-empty contents. */
2427f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)	return SECFailure;
2428f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    }
2429f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    *scts = *data;
2430f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    /* Keep track of negotiated extensions. */
2431f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    ss->xtnData.negotiated[ss->xtnData.numNegotiated++] = ex_type;
2432f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    return SECSuccess;
2433f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
2434